Skip to content

Commit

Permalink
Auto merge of rust-lang#125899 - jieyouxu:rollup-edk4see, r=jieyouxu
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

 - rust-lang#121062 (Change f32::midpoint to upcast to f64)
 - rust-lang#125808 (Migrate `run-make/c-link-to-rust-dylib` to `rmake.rs`)
 - rust-lang#125886 (Migrate run make issue 15460)
 - rust-lang#125890 (Improve compiletest expected/not found formatting)
 - rust-lang#125896 (compiletest: fix outdated rmake.rs comment)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jun 2, 2024
2 parents eda9d7f + 619dd86 commit f8e81b3
Show file tree
Hide file tree
Showing 15 changed files with 232 additions and 75 deletions.
55 changes: 36 additions & 19 deletions library/core/src/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1030,25 +1030,42 @@ impl f32 {
/// ```
#[unstable(feature = "num_midpoint", issue = "110840")]
pub fn midpoint(self, other: f32) -> f32 {
const LO: f32 = f32::MIN_POSITIVE * 2.;
const HI: f32 = f32::MAX / 2.;

let (a, b) = (self, other);
let abs_a = a.abs_private();
let abs_b = b.abs_private();

if abs_a <= HI && abs_b <= HI {
// Overflow is impossible
(a + b) / 2.
} else if abs_a < LO {
// Not safe to halve a
a + (b / 2.)
} else if abs_b < LO {
// Not safe to halve b
(a / 2.) + b
} else {
// Not safe to halve a and b
(a / 2.) + (b / 2.)
cfg_if! {
if #[cfg(any(
target_arch = "x86_64",
target_arch = "aarch64",
all(any(target_arch="riscv32", target_arch= "riscv64"), target_feature="d"),
all(target_arch = "arm", target_feature="vfp2"),
target_arch = "wasm32",
target_arch = "wasm64",
))] {
// whitelist the faster implementation to targets that have known good 64-bit float
// implementations. Falling back to the branchy code on targets that don't have
// 64-bit hardware floats or buggy implementations.
// see: https://github.com/rust-lang/rust/pull/121062#issuecomment-2123408114
((f64::from(self) + f64::from(other)) / 2.0) as f32
} else {
const LO: f32 = f32::MIN_POSITIVE * 2.;
const HI: f32 = f32::MAX / 2.;

let (a, b) = (self, other);
let abs_a = a.abs_private();
let abs_b = b.abs_private();

if abs_a <= HI && abs_b <= HI {
// Overflow is impossible
(a + b) / 2.
} else if abs_a < LO {
// Not safe to halve a
a + (b / 2.)
} else if abs_b < LO {
// Not safe to halve b
(a / 2.) + b
} else {
// Not safe to halve a and b
(a / 2.) + (b / 2.)
}
}
}
}

Expand Down
29 changes: 26 additions & 3 deletions library/core/tests/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ assume_usize_width! {
}

macro_rules! test_float {
($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr, $min: expr, $max: expr, $min_pos: expr) => {
($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr, $min: expr, $max: expr, $min_pos: expr, $max_exp:expr) => {
mod $modname {
#[test]
fn min() {
Expand Down Expand Up @@ -880,6 +880,27 @@ macro_rules! test_float {
assert!(($nan as $fty).midpoint(1.0).is_nan());
assert!((1.0 as $fty).midpoint($nan).is_nan());
assert!(($nan as $fty).midpoint($nan).is_nan());

// test if large differences in magnitude are still correctly computed.
// NOTE: that because of how small x and y are, x + y can never overflow
// so (x + y) / 2.0 is always correct
// in particular, `2.pow(i)` will never be at the max exponent, so it could
// be safely doubled, while j is significantly smaller.
for i in $max_exp.saturating_sub(64)..$max_exp {
for j in 0..64u8 {
let large = <$fty>::from(2.0f32).powi(i);
// a much smaller number, such that there is no chance of overflow to test
// potential double rounding in midpoint's implementation.
let small = <$fty>::from(2.0f32).powi($max_exp - 1)
* <$fty>::EPSILON
* <$fty>::from(j);

let naive = (large + small) / 2.0;
let midpoint = large.midpoint(small);

assert_eq!(naive, midpoint);
}
}
}
#[test]
fn rem_euclid() {
Expand Down Expand Up @@ -912,7 +933,8 @@ test_float!(
f32::NAN,
f32::MIN,
f32::MAX,
f32::MIN_POSITIVE
f32::MIN_POSITIVE,
f32::MAX_EXP
);
test_float!(
f64,
Expand All @@ -922,5 +944,6 @@ test_float!(
f64::NAN,
f64::MIN,
f64::MAX,
f64::MIN_POSITIVE
f64::MIN_POSITIVE,
f64::MAX_EXP
);
12 changes: 12 additions & 0 deletions src/tools/compiletest/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ pub struct Error {
pub msg: String,
}

impl Error {
pub fn render_for_expected(&self) -> String {
use colored::Colorize;
format!(
"{: <10}line {: >3}: {}",
self.kind.map(|kind| kind.to_string()).unwrap_or_default().to_uppercase(),
self.line_num,
self.msg.cyan(),
)
}
}

#[derive(PartialEq, Debug)]
enum WhichLine {
ThisLine,
Expand Down
10 changes: 9 additions & 1 deletion src/tools/compiletest/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
use std::{env, sync::Arc};
use std::{env, io::IsTerminal, sync::Arc};

use compiletest::{common::Mode, log_config, parse_config, run_tests};

fn main() {
tracing_subscriber::fmt::init();

// colored checks stdout by default, but for some reason only stderr is a terminal.
// compiletest *does* print many things to stdout, but it doesn't really matter.
if std::io::stderr().is_terminal()
&& matches!(std::env::var("NO_COLOR").as_deref(), Err(_) | Ok("0"))
{
colored::control::set_override(true);
}

let config = Arc::new(parse_config(env::args().collect()));

if config.valgrind_path.is_none() && config.force_valgrind {
Expand Down
29 changes: 19 additions & 10 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ use crate::json;
use crate::read2::{read2_abbreviated, Truncated};
use crate::util::{add_dylib_path, dylib_env_var, logv, PathBufExt};
use crate::ColorConfig;
use colored::Colorize;
use miropt_test_tools::{files_for_miropt_test, MiroptTest, MiroptTestFile};
use regex::{Captures, Regex};
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};

use std::collections::{HashMap, HashSet};
use std::env;
use std::ffi::{OsStr, OsString};
Expand Down Expand Up @@ -1493,14 +1493,22 @@ impl<'test> TestCx<'test> {
unexpected.len(),
not_found.len()
));
println!("status: {}\ncommand: {}", proc_res.status, proc_res.cmdline);
println!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline);
if !unexpected.is_empty() {
println!("unexpected errors (from JSON output): {:#?}\n", unexpected);
println!("{}", "--- unexpected errors (from JSON output) ---".green());
for error in &unexpected {
println!("{}", error.render_for_expected());
}
println!("{}", "---".green());
}
if !not_found.is_empty() {
println!("not found errors (from test file): {:#?}\n", not_found);
println!("{}", "--- not found errors (from test file) ---".red());
for error in &not_found {
println!("{}", error.render_for_expected());
}
println!("{}", "---\n".red());
}
panic!();
panic!("errors differ from expected");
}
}

Expand Down Expand Up @@ -3369,6 +3377,7 @@ impl<'test> TestCx<'test> {
cmd.env("IS_MSVC", "1")
.env("IS_WINDOWS", "1")
.env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
.env("MSVC_LIB_PATH", format!("{}", lib.display()))
.env("CC", format!("'{}' {}", self.config.cc, cflags))
.env("CXX", format!("'{}' {}", &self.config.cxx, cxxflags));
} else {
Expand Down Expand Up @@ -3435,13 +3444,13 @@ impl<'test> TestCx<'test> {
// ```
// base_dir/
// rmake.exe
// scratch/
// rmake_out/
// ```
// having the executable separate from the scratch directory allows the recipes to
// `remove_dir_all(scratch)` without running into permission denied issues because
// the executable is not under the `scratch/` directory.
// having the executable separate from the output artifacts directory allows the recipes to
// `remove_dir_all($TMPDIR)` without running into permission denied issues because
// the executable is not under the `rmake_out/` directory.
//
// This setup diverges from legacy Makefile run-make tests.
// This setup intentionally diverges from legacy Makefile run-make tests.
let base_dir = cwd.join(self.output_base_name());
if base_dir.exists() {
self.aggressive_rm_rf(&base_dir).unwrap();
Expand Down
82 changes: 70 additions & 12 deletions src/tools/run-make-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,23 @@ pub fn dynamic_lib_name(name: &str) -> String {
// ```
assert!(!name.contains(char::is_whitespace), "dynamic library name cannot contain whitespace");

let extension = dynamic_lib_extension();
if is_darwin() {
format!("lib{name}.dylib")
format!("lib{name}.{extension}")
} else if is_windows() {
format!("{name}.dll")
format!("{name}.{extension}")
} else {
format!("lib{name}.so")
format!("lib{name}.{extension}")
}
}

pub fn dynamic_lib_extension() -> &'static str {
if is_darwin() {
"dylib"
} else if is_windows() {
"dll"
} else {
"so"
}
}

Expand All @@ -149,6 +160,50 @@ pub fn bin_name(name: &str) -> String {
if is_windows() { format!("{name}.exe") } else { name.to_string() }
}

fn ar<P: AsRef<str>, P2: AsRef<str>>(obj_path: P, lib_path: P2, caller_line_number: u32) {
let mut ar = Command::new(env::var("AR").unwrap());
ar.current_dir(tmp_dir()).arg("crus").arg(lib_path.as_ref()).arg(obj_path.as_ref());
let output = ar.output().unwrap();
if !output.status.success() {
handle_failed_output(&ar, output, caller_line_number);
}
}

/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
#[track_caller]
pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
let caller_location = std::panic::Location::caller();
let caller_line_number = caller_location.line();

let obj_file = format!("{lib_name}.o");
let src = format!("{lib_name}.c");
let lib_name = if is_msvc() {
let lib_path = format!("lib{lib_name}.lib");
// First compiling `.c` to `.o`.
cc().arg("-c").out_exe(lib_name).input(src).run();
// Generating `.lib` from `.o`.
let mut msvc_lib = Command::new(env::var("MSVC_LIB_PATH").unwrap());
msvc_lib
.current_dir(tmp_dir())
.arg("-nologo")
.arg(&format!("-out:{}", cygpath_windows(&lib_path)))
.arg(&obj_file);
let output = msvc_lib.output().unwrap();
if !output.status.success() {
handle_failed_output(&msvc_lib, output, caller_line_number);
}
lib_path
} else {
let lib_path = format!("lib{lib_name}.a");
// First compiling `.c` to `.o`.
cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run();
// Generating `.a` from `.o`.
ar(obj_file, &lib_path, caller_line_number);
lib_path
};
tmp_dir().join(lib_name)
}

/// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
/// available on the platform!
#[track_caller]
Expand Down Expand Up @@ -249,16 +304,13 @@ pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
}

let dir2 = dir2.as_ref();
for entry in fs::read_dir(dir1).unwrap() {
let entry = entry.unwrap();
let entry_name = entry.file_name();
let path = entry.path();

if path.is_dir() {
recursive_diff(&path, &dir2.join(entry_name));
read_dir(dir1, |entry_path| {
let entry_name = entry_path.file_name().unwrap();
if entry_path.is_dir() {
recursive_diff(&entry_path, &dir2.join(entry_name));
} else {
let path2 = dir2.join(entry_name);
let file1 = read_file(&path);
let file1 = read_file(&entry_path);
let file2 = read_file(&path2);

// We don't use `assert_eq!` because they are `Vec<u8>`, so not great for display.
Expand All @@ -267,10 +319,16 @@ pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
assert!(
file1 == file2,
"`{}` and `{}` have different content",
path.display(),
entry_path.display(),
path2.display(),
);
}
});
}

pub fn read_dir<F: Fn(&Path)>(dir: impl AsRef<Path>, callback: F) {
for entry in fs::read_dir(dir).unwrap() {
callback(&entry.unwrap().path());
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/tools/run-make-support/src/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ impl Rustc {
self
}

pub fn extra_filename(&mut self, extra: &str) -> &mut Self {
self.cmd.arg(format!("-Cextra-filename={extra}"));
self
}

/// Specify a stdin input
pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
self.stdin = Some(input.as_ref().to_vec().into_boxed_slice());
Expand Down
2 changes: 0 additions & 2 deletions src/tools/tidy/src/allowed_run_make_makefiles.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ run-make/bare-outfile/Makefile
run-make/branch-protection-check-IBT/Makefile
run-make/c-dynamic-dylib/Makefile
run-make/c-dynamic-rlib/Makefile
run-make/c-link-to-rust-dylib/Makefile
run-make/c-static-dylib/Makefile
run-make/c-static-rlib/Makefile
run-make/c-unwind-abi-catch-lib-panic/Makefile
Expand Down Expand Up @@ -86,7 +85,6 @@ run-make/issue-107094/Makefile
run-make/issue-10971-temps-dir/Makefile
run-make/issue-109934-lto-debuginfo/Makefile
run-make/issue-14698/Makefile
run-make/issue-15460/Makefile
run-make/issue-18943/Makefile
run-make/issue-20626/Makefile
run-make/issue-22131/Makefile
Expand Down
21 changes: 0 additions & 21 deletions tests/run-make/c-link-to-rust-dylib/Makefile

This file was deleted.

Loading

0 comments on commit f8e81b3

Please sign in to comment.