From a7e0bab76bf28f7fe9791a2b412f8bccb061696f Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sun, 18 Sep 2022 20:23:32 +0100 Subject: [PATCH 1/5] rand: freebsd update, using getrandom. supported since the 12th release, while 11.4 is EOL since 2021. --- library/std/src/sys/unix/rand.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/unix/rand.rs b/library/std/src/sys/unix/rand.rs index a6fe07873d7ee..e846f885044f9 100644 --- a/library/std/src/sys/unix/rand.rs +++ b/library/std/src/sys/unix/rand.rs @@ -16,7 +16,6 @@ pub fn hashmap_random_keys() -> (u64, u64) { not(target_os = "ios"), not(target_os = "watchos"), not(target_os = "openbsd"), - not(target_os = "freebsd"), not(target_os = "netbsd"), not(target_os = "fuchsia"), not(target_os = "redox"), @@ -65,11 +64,25 @@ mod imp { unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) } } + #[cfg(target_os = "freebsd")] + fn getrandom(buf: &mut [u8]) -> libc::ssize_t { + // FIXME: using the above when libary std's libc is updated + extern "C" { + fn getrandom( + buffer: *mut libc::c_void, + length: libc::size_t, + flags: libc::c_uint, + ) -> libc::ssize_t; + } + unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) } + } + #[cfg(not(any( target_os = "linux", target_os = "android", target_os = "espidf", - target_os = "horizon" + target_os = "horizon", + target_os = "freebsd" )))] fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool { false @@ -79,7 +92,8 @@ mod imp { target_os = "linux", target_os = "android", target_os = "espidf", - target_os = "horizon" + target_os = "horizon", + target_os = "freebsd" ))] fn getrandom_fill_bytes(v: &mut [u8]) -> bool { use crate::sync::atomic::{AtomicBool, Ordering}; @@ -219,7 +233,7 @@ mod imp { } } -#[cfg(any(target_os = "freebsd", target_os = "netbsd"))] +#[cfg(target_os = "netbsd")] mod imp { use crate::ptr; From 4dc5e6181fbbf7130e20ef3856099107297255cd Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Fri, 10 Mar 2023 12:50:02 +0100 Subject: [PATCH 2/5] Regression test `println!()` panic message on `ErrorKind::BrokenPipe` No existing test failed if the [`panic!()`][1] of the `println!()` family of functions was removed, or if its message was changed. So add such a test. [1] https://github.com/rust-lang/rust/blob/104f4300cfddbd956e32820ef202a732f06ec848/library/std/src/io/stdio.rs#L1007-L1009 --- tests/ui/process/println-with-broken-pipe.rs | 43 +++++++++++++++++++ .../println-with-broken-pipe.run.stderr | 2 + .../println-with-broken-pipe.run.stdout | 1 + 3 files changed, 46 insertions(+) create mode 100644 tests/ui/process/println-with-broken-pipe.rs create mode 100644 tests/ui/process/println-with-broken-pipe.run.stderr create mode 100644 tests/ui/process/println-with-broken-pipe.run.stdout diff --git a/tests/ui/process/println-with-broken-pipe.rs b/tests/ui/process/println-with-broken-pipe.rs new file mode 100644 index 0000000000000..38b6bb4b3e229 --- /dev/null +++ b/tests/ui/process/println-with-broken-pipe.rs @@ -0,0 +1,43 @@ +// run-pass +// check-run-results +// ignore-windows +// ignore-emscripten +// ignore-fuchsia +// ignore-horizon +// ignore-android +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" + +// Test what the error message looks like when `println!()` panics because of +// `std::io::ErrorKind::BrokenPipe` + +#![feature(unix_sigpipe)] + +use std::env; +use std::process::{Command, Stdio}; + +#[unix_sigpipe = "sig_ign"] +fn main() { + let mut args = env::args(); + let me = args.next().unwrap(); + + if let Some(arg) = args.next() { + // More than enough iterations to fill any pipe buffer. Normally this + // loop will end with a panic more or less immediately. + for _ in 0..65536 * 64 { + println!("{arg}"); + } + unreachable!("should have panicked because of BrokenPipe"); + } + + // Set up a pipeline with a short-lived consumer and wait for it to finish. + // This will produce the `println!()` panic message on stderr. + let mut producer = Command::new(&me) + .arg("this line shall appear exactly once on stdout") + .stdout(Stdio::piped()) + .spawn() + .unwrap(); + let mut consumer = + Command::new("head").arg("-n1").stdin(producer.stdout.take().unwrap()).spawn().unwrap(); + consumer.wait().unwrap(); + producer.wait().unwrap(); +} diff --git a/tests/ui/process/println-with-broken-pipe.run.stderr b/tests/ui/process/println-with-broken-pipe.run.stderr new file mode 100644 index 0000000000000..ebcd920d501ff --- /dev/null +++ b/tests/ui/process/println-with-broken-pipe.run.stderr @@ -0,0 +1,2 @@ +thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', library/std/src/io/stdio.rs:LL:CC +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/tests/ui/process/println-with-broken-pipe.run.stdout b/tests/ui/process/println-with-broken-pipe.run.stdout new file mode 100644 index 0000000000000..f55c39578b104 --- /dev/null +++ b/tests/ui/process/println-with-broken-pipe.run.stdout @@ -0,0 +1 @@ +this line shall appear exactly once on stdout From 8c31219d5c6fe11654060ab968285705f00b1ec8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 20 Jul 2023 09:52:26 +1000 Subject: [PATCH 3/5] Tweak CGU sorting in a couple of places. In `base.rs`, tweak how the CGU size interleaving works. Since #113777, it's much more common to have multiple CGUs with identical sizes. With the existing code these same-sized items ended up in the opposite-to-desired order due to the stable sorting. The code now starts with a reverse sort (like is done in `partitioning.rs`) which gives the behaviour we want. This doesn't matter much for perf, but makes profiles in `samply` look more like what we expect. In `partitioning.rs`, we can use `sort_by_key` instead of `sort_by_cached_key` because `CGU::size_estimate()` is cheap. (There is an identical CGU sort earlier in that function that already uses `sort_by_key`.) --- compiler/rustc_codegen_ssa/src/base.rs | 5 +++-- compiler/rustc_monomorphize/src/partitioning.rs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index dc86280327492..79c284ecfbfa0 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -38,6 +38,7 @@ use rustc_span::symbol::sym; use rustc_span::Symbol; use rustc_target::abi::{Align, FIRST_VARIANT}; +use std::cmp; use std::collections::BTreeSet; use std::time::{Duration, Instant}; @@ -682,10 +683,10 @@ pub fn codegen_crate( // are large size variations, this can reduce memory usage significantly. let codegen_units: Vec<_> = { let mut sorted_cgus = codegen_units.iter().collect::>(); - sorted_cgus.sort_by_cached_key(|cgu| cgu.size_estimate()); + sorted_cgus.sort_by_key(|cgu| cmp::Reverse(cgu.size_estimate())); let (first_half, second_half) = sorted_cgus.split_at(sorted_cgus.len() / 2); - second_half.iter().rev().interleave(first_half).copied().collect() + first_half.iter().interleave(second_half.iter().rev()).copied().collect() }; // Calculate the CGU reuse diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 71aef53192f48..4a9d6c9e6c8c2 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -394,7 +394,7 @@ fn merge_codegen_units<'tcx>( && codegen_units.iter().any(|cgu| cgu.size_estimate() < NON_INCR_MIN_CGU_SIZE) { // Sort small cgus to the back. - codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate())); + codegen_units.sort_by_key(|cgu| cmp::Reverse(cgu.size_estimate())); let mut smallest = codegen_units.pop().unwrap(); let second_smallest = codegen_units.last_mut().unwrap(); From 2d92f4f2aa88b8f1740fd2d593b82820cdd336c5 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 25 Jul 2023 14:00:56 -0700 Subject: [PATCH 4/5] Remove -Z diagnostic-width --- compiler/rustc_session/src/options.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index ff433fdf16dc4..16d2029626eb6 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1433,8 +1433,6 @@ options! { dep_tasks: bool = (false, parse_bool, [UNTRACKED], "print tasks that execute and the color their dep node gets (requires debug build) \ (default: no)"), - diagnostic_width: Option = (None, parse_opt_number, [UNTRACKED], - "set the current output width for diagnostic truncation"), dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED], "emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) \ (default: no)"), From 1584e5f7c826ef40e07a0be3540f68116c855e92 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 21 Jul 2023 18:17:12 -0700 Subject: [PATCH 5/5] Squelch a noisy rustc_expand unittest --- compiler/rustc_expand/src/parse/tests.rs | 12 +++-- compiler/rustc_expand/src/tests.rs | 69 ++++++++++++++++-------- 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_expand/src/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs index 8b37728b60fea..e133501c5d0a8 100644 --- a/compiler/rustc_expand/src/parse/tests.rs +++ b/compiler/rustc_expand/src/parse/tests.rs @@ -1,4 +1,6 @@ -use crate::tests::{matches_codepattern, string_to_stream, with_error_checking_parse}; +use crate::tests::{ + matches_codepattern, string_to_stream, with_error_checking_parse, with_expected_parse_error, +}; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token}; @@ -51,11 +53,15 @@ fn string_to_item(source_str: String) -> Option> { with_error_checking_parse(source_str, &sess(), |p| p.parse_item(ForceCollect::No)) } -#[should_panic] #[test] fn bad_path_expr_1() { + // This should trigger error: expected identifier, found keyword `return` create_default_session_globals_then(|| { - string_to_expr("::abc::def::return".to_string()); + with_expected_parse_error( + "::abc::def::return", + "expected identifier, found keyword `return`", + |p| p.parse_expr(), + ); }) } diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index 6490e52955db8..67c268667c6bd 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -22,6 +22,33 @@ fn string_to_parser(ps: &ParseSess, source_str: String) -> Parser<'_> { new_parser_from_source_str(ps, PathBuf::from("bogofile").into(), source_str) } +fn create_test_handler() -> (Handler, Lrc, Arc>>) { + let output = Arc::new(Mutex::new(Vec::new())); + let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + false, + ); + let emitter = EmitterWriter::new( + Box::new(Shared { data: output.clone() }), + Some(source_map.clone()), + None, + fallback_bundle, + false, + false, + false, + Some(140), + false, + false, + TerminalUrl::No, + ); + let handler = Handler::with_emitter(true, None, Box::new(emitter), None); + (handler, source_map, output) +} + +/// Returns the result of parsing the given string via the given callback. +/// +/// If there are any errors, this will panic. pub(crate) fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T where F: FnOnce(&mut Parser<'a>) -> PResult<'a, T>, @@ -32,6 +59,26 @@ where x } +/// Verifies that parsing the given string using the given callback will +/// generate an error that contains the given text. +pub(crate) fn with_expected_parse_error(source_str: &str, expected_output: &str, f: F) +where + F: for<'a> FnOnce(&mut Parser<'a>) -> PResult<'a, T>, +{ + let (handler, source_map, output) = create_test_handler(); + let ps = ParseSess::with_span_handler(handler, source_map); + let mut p = string_to_parser(&ps, source_str.to_string()); + let result = f(&mut p); + assert!(result.is_ok()); + + let bytes = output.lock().unwrap(); + let actual_output = str::from_utf8(&bytes).unwrap(); + println!("expected output:\n------\n{}------", expected_output); + println!("actual output:\n------\n{}------", actual_output); + + assert!(actual_output.contains(expected_output)) +} + /// Maps a string to tts, using a made-up filename. pub(crate) fn string_to_stream(source_str: String) -> TokenStream { let ps = ParseSess::new( @@ -130,13 +177,7 @@ impl Write for Shared { fn test_harness(file_text: &str, span_labels: Vec, expected_output: &str) { create_default_session_if_not_set_then(|_| { - let output = Arc::new(Mutex::new(Vec::new())); - - let fallback_bundle = rustc_errors::fallback_fluent_bundle( - vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], - false, - ); - let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let (handler, source_map, output) = create_test_handler(); source_map.new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned()); let primary_span = make_span(&file_text, &span_labels[0].start, &span_labels[0].end); @@ -148,20 +189,6 @@ fn test_harness(file_text: &str, span_labels: Vec, expected_output: & println!("text: {:?}", source_map.span_to_snippet(span)); } - let emitter = EmitterWriter::new( - Box::new(Shared { data: output.clone() }), - Some(source_map.clone()), - None, - fallback_bundle, - false, - false, - false, - None, - false, - false, - TerminalUrl::No, - ); - let handler = Handler::with_emitter(true, None, Box::new(emitter), None); #[allow(rustc::untranslatable_diagnostic)] handler.span_err(msp, "foo");