diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 3fdfb08f5847b..cf1c60588978c 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -843,19 +843,18 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( let msg_bus = "clang: error: unable to execute command: Bus error: 10"; if out.contains(msg_segv) || out.contains(msg_bus) { warn!( + ?cmd, %out, "looks like the linker segfaulted when we tried to call it, \ - automatically retrying again. cmd = {:?}, out = {}.", - cmd, out, + automatically retrying again", ); continue; } if is_illegal_instruction(&output.status) { warn!( + ?cmd, %out, status = %output.status, "looks like the linker hit an illegal instruction when we \ - tried to call it, automatically retrying again. cmd = {:?}, ]\ - out = {}, status = {}.", - cmd, out, output.status, + tried to call it, automatically retrying again.", ); continue; } diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index ab7ee03b643f8..05c7e11cbc29a 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1253,12 +1253,16 @@ pub fn init_rustc_env_logger() { /// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to choose an env var /// other than `RUSTC_LOG`. pub fn init_env_logger(env: &str) { - // Don't register a dispatcher if there's no filter to print anything - match std::env::var(env) { - Err(_) => return, - Ok(s) if s.is_empty() => return, - Ok(_) => {} - } + use tracing_subscriber::{ + filter::{self, EnvFilter, LevelFilter}, + layer::SubscriberExt, + }; + + let filter = match std::env::var(env) { + Ok(env) => EnvFilter::from_env(env), + _ => EnvFilter::default().add_directive(filter::Directive::from(LevelFilter::WARN)), + }; + let color_logs = match std::env::var(String::from(env) + "_COLOR") { Ok(value) => match value.as_ref() { "always" => true, @@ -1278,7 +1282,7 @@ pub fn init_env_logger(env: &str) { "non-Unicode log color value: expected one of always, never, or auto", ), }; - let filter = tracing_subscriber::EnvFilter::from_env(env); + let layer = tracing_tree::HierarchicalLayer::default() .with_writer(io::stderr) .with_indent_lines(true) @@ -1288,7 +1292,6 @@ pub fn init_env_logger(env: &str) { #[cfg(parallel_compiler)] let layer = layer.with_thread_ids(true).with_thread_names(true); - use tracing_subscriber::layer::SubscriberExt; let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer); tracing::subscriber::set_global_default(subscriber).unwrap(); } diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 29f352ae58559..778d58eeadcf0 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2308,7 +2308,7 @@ pub fn is_case_difference(sm: &SourceMap, suggested: &str, sp: Span) -> bool { let found = match sm.span_to_snippet(sp) { Ok(snippet) => snippet, Err(e) => { - warn!("Invalid span {:?}. Err={:?}", sp, e); + warn!(error = ?e, "Invalid span {:?}", sp); return false; } }; diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 2ef0e0f6b1e56..55ec3703df8f8 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -288,7 +288,7 @@ declare_features! ( (accepted, member_constraints, "1.54.0", Some(61997), None), /// Allows bindings in the subpattern of a binding pattern. /// For example, you can write `x @ Some(y)`. - (accepted, bindings_after_at, "1.54.0", Some(65490), None), + (accepted, bindings_after_at, "1.56.0", Some(65490), None), /// Allows calling `transmute` in const fn (accepted, const_fn_transmute, "1.56.0", Some(53605), None), /// Allows accessing fields of unions inside `const` functions. diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index 29ffed9934421..c0bf4b659aa96 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -289,7 +289,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeMutBorrowedLocals<'_, 'tcx> { flow_state: &BitSet, call: PeekCall, ) { - warn!("peek_at: place={:?}", place); + info!(?place, "peek_at"); let local = if let Some(l) = place.as_local() { l } else { @@ -311,7 +311,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeLiveLocals { flow_state: &BitSet, call: PeekCall, ) { - warn!("peek_at: place={:?}", place); + info!(?place, "peek_at"); let local = if let Some(l) = place.as_local() { l } else { diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 4c8ea6902ff14..860f21085f325 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -662,6 +662,8 @@ impl [u8] { /// /// [`make_ascii_uppercase`]: slice::make_ascii_uppercase #[cfg(not(no_global_oom_handling))] + #[must_use = "this returns the uppercase bytes as a new Vec, \ + without modifying the original"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_uppercase(&self) -> Vec { @@ -680,6 +682,8 @@ impl [u8] { /// /// [`make_ascii_lowercase`]: slice::make_ascii_lowercase #[cfg(not(no_global_oom_handling))] + #[must_use = "this returns the lowercase bytes as a new Vec, \ + without modifying the original"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_lowercase(&self) -> Vec { diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index 62ba2e5765507..2900d01d9bdae 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -367,6 +367,8 @@ impl str { /// assert_eq!(new_year, new_year.to_lowercase()); /// ``` #[cfg(not(no_global_oom_handling))] + #[must_use = "this returns the lowercase string as a new String, \ + without modifying the original"] #[stable(feature = "unicode_case_mapping", since = "1.2.0")] pub fn to_lowercase(&self) -> String { let mut s = String::with_capacity(self.len()); @@ -447,6 +449,8 @@ impl str { /// assert_eq!("TSCHÜSS", s.to_uppercase()); /// ``` #[cfg(not(no_global_oom_handling))] + #[must_use = "this returns the uppercase string as a new String, \ + without modifying the original"] #[stable(feature = "unicode_case_mapping", since = "1.2.0")] pub fn to_uppercase(&self) -> String { let mut s = String::with_capacity(self.len()); @@ -534,6 +538,7 @@ impl str { /// [`make_ascii_uppercase`]: str::make_ascii_uppercase /// [`to_uppercase`]: #method.to_uppercase #[cfg(not(no_global_oom_handling))] + #[must_use = "to uppercase the value in-place, use `make_ascii_lowercase()`"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_uppercase(&self) -> String { @@ -565,6 +570,7 @@ impl str { /// [`make_ascii_lowercase`]: str::make_ascii_lowercase /// [`to_lowercase`]: #method.to_lowercase #[cfg(not(no_global_oom_handling))] + #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_lowercase(&self) -> String { diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index b1dd6aef97493..b3af1f1ffb592 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -949,6 +949,8 @@ impl char { /// // convert into themselves. /// assert_eq!('山'.to_lowercase().to_string(), "山"); /// ``` + #[must_use = "this returns the lowercase character as a new iterator, \ + without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn to_lowercase(self) -> ToLowercase { @@ -1039,6 +1041,8 @@ impl char { /// ``` /// /// holds across languages. + #[must_use = "this returns the uppercase character as a new iterator, \ + without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn to_uppercase(self) -> ToUppercase { @@ -1085,6 +1089,7 @@ impl char { /// /// [`make_ascii_uppercase()`]: #method.make_ascii_uppercase /// [`to_uppercase()`]: #method.to_uppercase + #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase()`"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")] #[inline] @@ -1118,6 +1123,7 @@ impl char { /// /// [`make_ascii_lowercase()`]: #method.make_ascii_lowercase /// [`to_lowercase()`]: #method.to_lowercase + #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")] #[inline] diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index d5fb98eff575d..44918a711d470 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -282,6 +282,7 @@ impl u8 { /// ``` /// /// [`make_ascii_uppercase`]: Self::make_ascii_uppercase + #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase()`"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")] #[inline] @@ -306,6 +307,7 @@ impl u8 { /// ``` /// /// [`make_ascii_lowercase`]: Self::make_ascii_lowercase + #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")] #[inline] @@ -769,6 +771,8 @@ impl u8 { /// assert_eq!("\\\\", b'\\'.escape_ascii().to_string()); /// assert_eq!("\\x9d", b'\x9d'.escape_ascii().to_string()); /// ``` + #[must_use = "this returns the escaped byte as an iterator, \ + without modifying the original"] #[unstable(feature = "inherent_ascii_escape", issue = "77174")] #[inline] pub fn escape_ascii(&self) -> ascii::EscapeDefault { diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index b92ab7e347555..cbb5627cef982 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -72,6 +72,8 @@ impl [u8] { /// let escaped = s.escape_ascii().to_string(); /// assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d"); /// ``` + #[must_use = "this returns the escaped bytes as an iterator, \ + without modifying the original"] #[unstable(feature = "inherent_ascii_escape", issue = "77174")] pub fn escape_ascii(&self) -> EscapeAscii<'_> { EscapeAscii { inner: self.iter().flat_map(EscapeByte) } diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 607fb627605a0..f25ab52cfa0d0 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -798,6 +798,8 @@ impl str { /// /// assert_eq!(None, iter.next()); /// ``` + #[must_use = "this returns the split string as an iterator, \ + without modifying the original"] #[stable(feature = "split_whitespace", since = "1.1.0")] #[inline] pub fn split_whitespace(&self) -> SplitWhitespace<'_> { @@ -839,6 +841,8 @@ impl str { /// /// assert_eq!(None, iter.next()); /// ``` + #[must_use = "this returns the split string as an iterator, \ + without modifying the original"] #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] #[inline] pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace<'_> { @@ -914,6 +918,8 @@ impl str { /// /// assert!(utf16_len <= utf8_len); /// ``` + #[must_use = "this returns the encoded string as an iterator, \ + without modifying the original"] #[stable(feature = "encode_utf16", since = "1.8.0")] pub fn encode_utf16(&self) -> EncodeUtf16<'_> { EncodeUtf16 { chars: self.chars(), extra: 0 } @@ -1353,6 +1359,9 @@ impl str { /// /// let v: Vec<&str> = "A..B..".split_terminator(".").collect(); /// assert_eq!(v, ["A", "", "B", ""]); + /// + /// let v: Vec<&str> = "A.B:C.D".split_terminator(&['.', ':'][..]).collect(); + /// assert_eq!(v, ["A", "B", "C", "D"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -1396,6 +1405,9 @@ impl str { /// /// let v: Vec<&str> = "A..B..".rsplit_terminator(".").collect(); /// assert_eq!(v, ["", "B", "", "A"]); + /// + /// let v: Vec<&str> = "A.B:C.D".rsplit_terminator(&['.', ':'][..]).collect(); + /// assert_eq!(v, ["D", "C", "B", "A"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -1840,6 +1852,8 @@ impl str { /// let s = " עברית"; /// assert!(Some('ע') == s.trim_left().chars().next()); /// ``` + #[must_use = "this returns the trimmed string as a new slice, \ + without modifying the original"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated( @@ -1882,6 +1896,8 @@ impl str { /// let s = "עברית "; /// assert!(Some('ת') == s.trim_right().chars().rev().next()); /// ``` + #[must_use = "this returns the trimmed string as a new slice, \ + without modifying the original"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated( @@ -2346,6 +2362,8 @@ impl str { /// ``` /// assert_eq!("❤\n!".escape_debug().to_string(), "❤\\n!"); /// ``` + #[must_use = "this returns the escaped string as an iterator, \ + without modifying the original"] #[stable(feature = "str_escape", since = "1.34.0")] pub fn escape_debug(&self) -> EscapeDebug<'_> { let mut chars = self.chars(); @@ -2390,6 +2408,8 @@ impl str { /// ``` /// assert_eq!("❤\n!".escape_default().to_string(), "\\u{2764}\\n!"); /// ``` + #[must_use = "this returns the escaped string as an iterator, \ + without modifying the original"] #[stable(feature = "str_escape", since = "1.34.0")] pub fn escape_default(&self) -> EscapeDefault<'_> { EscapeDefault { inner: self.chars().flat_map(CharEscapeDefault) } @@ -2426,6 +2446,8 @@ impl str { /// ``` /// assert_eq!("❤\n!".escape_unicode().to_string(), "\\u{2764}\\u{a}\\u{21}"); /// ``` + #[must_use = "this returns the escaped string as an iterator, \ + without modifying the original"] #[stable(feature = "str_escape", since = "1.34.0")] pub fn escape_unicode(&self) -> EscapeUnicode<'_> { EscapeUnicode { inner: self.chars().flat_map(CharEscapeUnicode) } diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 7e70901076cda..c305519dd4461 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -777,6 +777,7 @@ impl OsStr { /// /// assert_eq!("grüße, jürgen ❤", s.to_ascii_lowercase()); /// ``` + #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase`"] #[stable(feature = "osstring_ascii", since = "1.53.0")] pub fn to_ascii_lowercase(&self) -> OsString { OsString::from_inner(self.inner.to_ascii_lowercase()) @@ -798,6 +799,7 @@ impl OsStr { /// /// assert_eq!("GRüßE, JüRGEN ❤", s.to_ascii_uppercase()); /// ``` + #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase`"] #[stable(feature = "osstring_ascii", since = "1.53.0")] pub fn to_ascii_uppercase(&self) -> OsString { OsString::from_inner(self.inner.to_ascii_uppercase()) diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 14a63303711fc..1ac3bbc95c66d 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -256,6 +256,7 @@ pub struct Stdin { /// Ok(()) /// } /// ``` +#[must_use = "if unused stdin will immediately unlock"] #[stable(feature = "rust1", since = "1.0.0")] pub struct StdinLock<'a> { inner: MutexGuard<'a, BufReader>, @@ -624,6 +625,7 @@ pub struct Stdout { /// When operating in a console, the Windows implementation of this stream does not support /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return /// an error. +#[must_use = "if unused stdout will immediately unlock"] #[stable(feature = "rust1", since = "1.0.0")] pub struct StdoutLock<'a> { inner: ReentrantMutexGuard<'a, RefCell>>, @@ -907,6 +909,7 @@ pub struct Stderr { /// When operating in a console, the Windows implementation of this stream does not support /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return /// an error. +#[must_use = "if unused stderr will immediately unlock"] #[stable(feature = "rust1", since = "1.0.0")] pub struct StderrLock<'a> { inner: ReentrantMutexGuard<'a, RefCell>, diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 707a55b625814..7d404aff30e07 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -412,9 +412,9 @@ impl Builder { /// /// # Safety /// - /// The caller has to ensure that no references in the supplied thread closure - /// or its return type can outlive the spawned thread's lifetime. This can be - /// guaranteed in two ways: + /// The caller has to ensure that the spawned thread does not outlive any + /// references in the supplied thread closure and its return type. + /// This can be guaranteed in two ways: /// /// - ensure that [`join`][`JoinHandle::join`] is called before any referenced /// data is dropped diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index ccaf6e8733e0c..a2afa88028fea 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -613,8 +613,8 @@ Each register class has constraints on which value types they can be used with. | x86 | `xmm_reg` | `sse` | `i32`, `f32`, `i64`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | | x86 | `ymm_reg` | `avx` | `i32`, `f32`, `i64`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2`
`i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` | | x86 | `zmm_reg` | `avx512f` | `i32`, `f32`, `i64`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2`
`i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4`
`i8x64`, `i16x32`, `i32x16`, `i64x8`, `f32x16`, `f64x8` | -| x86 | `kreg` | `axv512f` | `i8`, `i16` | -| x86 | `kreg` | `axv512bw` | `i32`, `i64` | +| x86 | `kreg` | `avx512f` | `i8`, `i16` | +| x86 | `kreg` | `avx512bw` | `i32`, `i64` | | x86 | `mmx_reg` | N/A | Only clobbers | | x86 | `x87_reg` | N/A | Only clobbers | | AArch64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | diff --git a/src/test/ui/consts/const_in_pattern/issue-73431.stderr b/src/test/ui/consts/const_in_pattern/issue-73431.stderr new file mode 100644 index 0000000000000..c82dea4aa50df --- /dev/null +++ b/src/test/ui/consts/const_in_pattern/issue-73431.stderr @@ -0,0 +1 @@ +WARN rustc_mir_build::thir::pattern::const_to_pat MIR const-checker found novel structural match violation. See #73448. diff --git a/src/tools/compiletest/src/read2.rs b/src/tools/compiletest/src/read2.rs index 30a922057eb20..897b9dd400793 100644 --- a/src/tools/compiletest/src/read2.rs +++ b/src/tools/compiletest/src/read2.rs @@ -2,6 +2,77 @@ // Consider unify the read2() in libstd, cargo and this to prevent further code duplication. pub use self::imp::read2; +use std::io; +use std::process::{Child, Output}; + +pub fn read2_abbreviated(mut child: Child) -> io::Result { + use io::Write; + use std::mem::replace; + + const HEAD_LEN: usize = 160 * 1024; + const TAIL_LEN: usize = 256 * 1024; + + enum ProcOutput { + Full(Vec), + Abbreviated { head: Vec, skipped: usize, tail: Box<[u8]> }, + } + + impl ProcOutput { + fn extend(&mut self, data: &[u8]) { + let new_self = match *self { + ProcOutput::Full(ref mut bytes) => { + bytes.extend_from_slice(data); + let new_len = bytes.len(); + if new_len <= HEAD_LEN + TAIL_LEN { + return; + } + let tail = bytes.split_off(new_len - TAIL_LEN).into_boxed_slice(); + let head = replace(bytes, Vec::new()); + let skipped = new_len - HEAD_LEN - TAIL_LEN; + ProcOutput::Abbreviated { head, skipped, tail } + } + ProcOutput::Abbreviated { ref mut skipped, ref mut tail, .. } => { + *skipped += data.len(); + if data.len() <= TAIL_LEN { + tail[..data.len()].copy_from_slice(data); + tail.rotate_left(data.len()); + } else { + tail.copy_from_slice(&data[(data.len() - TAIL_LEN)..]); + } + return; + } + }; + *self = new_self; + } + + fn into_bytes(self) -> Vec { + match self { + ProcOutput::Full(bytes) => bytes, + ProcOutput::Abbreviated { mut head, skipped, tail } => { + write!(&mut head, "\n\n<<<<<< SKIPPED {} BYTES >>>>>>\n\n", skipped).unwrap(); + head.extend_from_slice(&tail); + head + } + } + } + } + + let mut stdout = ProcOutput::Full(Vec::new()); + let mut stderr = ProcOutput::Full(Vec::new()); + + drop(child.stdin.take()); + read2( + child.stdout.take().unwrap(), + child.stderr.take().unwrap(), + &mut |is_stdout, data, _| { + if is_stdout { &mut stdout } else { &mut stderr }.extend(data); + data.clear(); + }, + )?; + let status = child.wait()?; + + Ok(Output { status, stdout: stdout.into_bytes(), stderr: stderr.into_bytes() }) +} #[cfg(not(any(unix, windows)))] mod imp { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 0821e279d2485..934839bbd605b 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -12,6 +12,7 @@ use crate::compute_diff::{write_diff, write_filtered_diff}; use crate::errors::{self, Error, ErrorKind}; use crate::header::TestProps; use crate::json; +use crate::read2::read2_abbreviated; use crate::util::get_pointer_width; use crate::util::{logv, PathBufExt}; use crate::ColorConfig; @@ -27,7 +28,7 @@ use std::hash::{Hash, Hasher}; use std::io::prelude::*; use std::io::{self, BufReader}; use std::path::{Path, PathBuf}; -use std::process::{Child, Command, ExitStatus, Output, Stdio}; +use std::process::{Command, ExitStatus, Output, Stdio}; use std::str; use glob::glob; @@ -3820,72 +3821,3 @@ enum AllowUnused { Yes, No, } - -fn read2_abbreviated(mut child: Child) -> io::Result { - use crate::read2::read2; - use std::mem::replace; - - const HEAD_LEN: usize = 160 * 1024; - const TAIL_LEN: usize = 256 * 1024; - - enum ProcOutput { - Full(Vec), - Abbreviated { head: Vec, skipped: usize, tail: Box<[u8]> }, - } - - impl ProcOutput { - fn extend(&mut self, data: &[u8]) { - let new_self = match *self { - ProcOutput::Full(ref mut bytes) => { - bytes.extend_from_slice(data); - let new_len = bytes.len(); - if new_len <= HEAD_LEN + TAIL_LEN { - return; - } - let tail = bytes.split_off(new_len - TAIL_LEN).into_boxed_slice(); - let head = replace(bytes, Vec::new()); - let skipped = new_len - HEAD_LEN - TAIL_LEN; - ProcOutput::Abbreviated { head, skipped, tail } - } - ProcOutput::Abbreviated { ref mut skipped, ref mut tail, .. } => { - *skipped += data.len(); - if data.len() <= TAIL_LEN { - tail[..data.len()].copy_from_slice(data); - tail.rotate_left(data.len()); - } else { - tail.copy_from_slice(&data[(data.len() - TAIL_LEN)..]); - } - return; - } - }; - *self = new_self; - } - - fn into_bytes(self) -> Vec { - match self { - ProcOutput::Full(bytes) => bytes, - ProcOutput::Abbreviated { mut head, skipped, tail } => { - write!(&mut head, "\n\n<<<<<< SKIPPED {} BYTES >>>>>>\n\n", skipped).unwrap(); - head.extend_from_slice(&tail); - head - } - } - } - } - - let mut stdout = ProcOutput::Full(Vec::new()); - let mut stderr = ProcOutput::Full(Vec::new()); - - drop(child.stdin.take()); - read2( - child.stdout.take().unwrap(), - child.stderr.take().unwrap(), - &mut |is_stdout, data, _| { - if is_stdout { &mut stdout } else { &mut stderr }.extend(data); - data.clear(); - }, - )?; - let status = child.wait()?; - - Ok(Output { status, stdout: stdout.into_bytes(), stderr: stderr.into_bytes() }) -}