Skip to content

Commit f8e81b3

Browse files
committed
Auto merge of #125899 - jieyouxu:rollup-edk4see, r=jieyouxu
Rollup of 5 pull requests Successful merges: - #121062 (Change f32::midpoint to upcast to f64) - #125808 (Migrate `run-make/c-link-to-rust-dylib` to `rmake.rs`) - #125886 (Migrate run make issue 15460) - #125890 (Improve compiletest expected/not found formatting) - #125896 (compiletest: fix outdated rmake.rs comment) r? `@ghost` `@rustbot` modify labels: rollup
2 parents eda9d7f + 619dd86 commit f8e81b3

File tree

15 files changed

+232
-75
lines changed

15 files changed

+232
-75
lines changed

library/core/src/num/f32.rs

+36-19
Original file line numberDiff line numberDiff line change
@@ -1030,25 +1030,42 @@ impl f32 {
10301030
/// ```
10311031
#[unstable(feature = "num_midpoint", issue = "110840")]
10321032
pub fn midpoint(self, other: f32) -> f32 {
1033-
const LO: f32 = f32::MIN_POSITIVE * 2.;
1034-
const HI: f32 = f32::MAX / 2.;
1035-
1036-
let (a, b) = (self, other);
1037-
let abs_a = a.abs_private();
1038-
let abs_b = b.abs_private();
1039-
1040-
if abs_a <= HI && abs_b <= HI {
1041-
// Overflow is impossible
1042-
(a + b) / 2.
1043-
} else if abs_a < LO {
1044-
// Not safe to halve a
1045-
a + (b / 2.)
1046-
} else if abs_b < LO {
1047-
// Not safe to halve b
1048-
(a / 2.) + b
1049-
} else {
1050-
// Not safe to halve a and b
1051-
(a / 2.) + (b / 2.)
1033+
cfg_if! {
1034+
if #[cfg(any(
1035+
target_arch = "x86_64",
1036+
target_arch = "aarch64",
1037+
all(any(target_arch="riscv32", target_arch= "riscv64"), target_feature="d"),
1038+
all(target_arch = "arm", target_feature="vfp2"),
1039+
target_arch = "wasm32",
1040+
target_arch = "wasm64",
1041+
))] {
1042+
// whitelist the faster implementation to targets that have known good 64-bit float
1043+
// implementations. Falling back to the branchy code on targets that don't have
1044+
// 64-bit hardware floats or buggy implementations.
1045+
// see: https://github.com/rust-lang/rust/pull/121062#issuecomment-2123408114
1046+
((f64::from(self) + f64::from(other)) / 2.0) as f32
1047+
} else {
1048+
const LO: f32 = f32::MIN_POSITIVE * 2.;
1049+
const HI: f32 = f32::MAX / 2.;
1050+
1051+
let (a, b) = (self, other);
1052+
let abs_a = a.abs_private();
1053+
let abs_b = b.abs_private();
1054+
1055+
if abs_a <= HI && abs_b <= HI {
1056+
// Overflow is impossible
1057+
(a + b) / 2.
1058+
} else if abs_a < LO {
1059+
// Not safe to halve a
1060+
a + (b / 2.)
1061+
} else if abs_b < LO {
1062+
// Not safe to halve b
1063+
(a / 2.) + b
1064+
} else {
1065+
// Not safe to halve a and b
1066+
(a / 2.) + (b / 2.)
1067+
}
1068+
}
10521069
}
10531070
}
10541071

library/core/tests/num/mod.rs

+26-3
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@ assume_usize_width! {
729729
}
730730

731731
macro_rules! test_float {
732-
($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr, $min: expr, $max: expr, $min_pos: expr) => {
732+
($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr, $min: expr, $max: expr, $min_pos: expr, $max_exp:expr) => {
733733
mod $modname {
734734
#[test]
735735
fn min() {
@@ -880,6 +880,27 @@ macro_rules! test_float {
880880
assert!(($nan as $fty).midpoint(1.0).is_nan());
881881
assert!((1.0 as $fty).midpoint($nan).is_nan());
882882
assert!(($nan as $fty).midpoint($nan).is_nan());
883+
884+
// test if large differences in magnitude are still correctly computed.
885+
// NOTE: that because of how small x and y are, x + y can never overflow
886+
// so (x + y) / 2.0 is always correct
887+
// in particular, `2.pow(i)` will never be at the max exponent, so it could
888+
// be safely doubled, while j is significantly smaller.
889+
for i in $max_exp.saturating_sub(64)..$max_exp {
890+
for j in 0..64u8 {
891+
let large = <$fty>::from(2.0f32).powi(i);
892+
// a much smaller number, such that there is no chance of overflow to test
893+
// potential double rounding in midpoint's implementation.
894+
let small = <$fty>::from(2.0f32).powi($max_exp - 1)
895+
* <$fty>::EPSILON
896+
* <$fty>::from(j);
897+
898+
let naive = (large + small) / 2.0;
899+
let midpoint = large.midpoint(small);
900+
901+
assert_eq!(naive, midpoint);
902+
}
903+
}
883904
}
884905
#[test]
885906
fn rem_euclid() {
@@ -912,7 +933,8 @@ test_float!(
912933
f32::NAN,
913934
f32::MIN,
914935
f32::MAX,
915-
f32::MIN_POSITIVE
936+
f32::MIN_POSITIVE,
937+
f32::MAX_EXP
916938
);
917939
test_float!(
918940
f64,
@@ -922,5 +944,6 @@ test_float!(
922944
f64::NAN,
923945
f64::MIN,
924946
f64::MAX,
925-
f64::MIN_POSITIVE
947+
f64::MIN_POSITIVE,
948+
f64::MAX_EXP
926949
);

src/tools/compiletest/src/errors.rs

+12
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ pub struct Error {
5757
pub msg: String,
5858
}
5959

60+
impl Error {
61+
pub fn render_for_expected(&self) -> String {
62+
use colored::Colorize;
63+
format!(
64+
"{: <10}line {: >3}: {}",
65+
self.kind.map(|kind| kind.to_string()).unwrap_or_default().to_uppercase(),
66+
self.line_num,
67+
self.msg.cyan(),
68+
)
69+
}
70+
}
71+
6072
#[derive(PartialEq, Debug)]
6173
enum WhichLine {
6274
ThisLine,

src/tools/compiletest/src/main.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1-
use std::{env, sync::Arc};
1+
use std::{env, io::IsTerminal, sync::Arc};
22

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

55
fn main() {
66
tracing_subscriber::fmt::init();
77

8+
// colored checks stdout by default, but for some reason only stderr is a terminal.
9+
// compiletest *does* print many things to stdout, but it doesn't really matter.
10+
if std::io::stderr().is_terminal()
11+
&& matches!(std::env::var("NO_COLOR").as_deref(), Err(_) | Ok("0"))
12+
{
13+
colored::control::set_override(true);
14+
}
15+
816
let config = Arc::new(parse_config(env::args().collect()));
917

1018
if config.valgrind_path.is_none() && config.force_valgrind {

src/tools/compiletest/src/runtest.rs

+19-10
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ use crate::json;
1717
use crate::read2::{read2_abbreviated, Truncated};
1818
use crate::util::{add_dylib_path, dylib_env_var, logv, PathBufExt};
1919
use crate::ColorConfig;
20+
use colored::Colorize;
2021
use miropt_test_tools::{files_for_miropt_test, MiroptTest, MiroptTestFile};
2122
use regex::{Captures, Regex};
2223
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
23-
2424
use std::collections::{HashMap, HashSet};
2525
use std::env;
2626
use std::ffi::{OsStr, OsString};
@@ -1493,14 +1493,22 @@ impl<'test> TestCx<'test> {
14931493
unexpected.len(),
14941494
not_found.len()
14951495
));
1496-
println!("status: {}\ncommand: {}", proc_res.status, proc_res.cmdline);
1496+
println!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline);
14971497
if !unexpected.is_empty() {
1498-
println!("unexpected errors (from JSON output): {:#?}\n", unexpected);
1498+
println!("{}", "--- unexpected errors (from JSON output) ---".green());
1499+
for error in &unexpected {
1500+
println!("{}", error.render_for_expected());
1501+
}
1502+
println!("{}", "---".green());
14991503
}
15001504
if !not_found.is_empty() {
1501-
println!("not found errors (from test file): {:#?}\n", not_found);
1505+
println!("{}", "--- not found errors (from test file) ---".red());
1506+
for error in &not_found {
1507+
println!("{}", error.render_for_expected());
1508+
}
1509+
println!("{}", "---\n".red());
15021510
}
1503-
panic!();
1511+
panic!("errors differ from expected");
15041512
}
15051513
}
15061514

@@ -3369,6 +3377,7 @@ impl<'test> TestCx<'test> {
33693377
cmd.env("IS_MSVC", "1")
33703378
.env("IS_WINDOWS", "1")
33713379
.env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
3380+
.env("MSVC_LIB_PATH", format!("{}", lib.display()))
33723381
.env("CC", format!("'{}' {}", self.config.cc, cflags))
33733382
.env("CXX", format!("'{}' {}", &self.config.cxx, cxxflags));
33743383
} else {
@@ -3435,13 +3444,13 @@ impl<'test> TestCx<'test> {
34353444
// ```
34363445
// base_dir/
34373446
// rmake.exe
3438-
// scratch/
3447+
// rmake_out/
34393448
// ```
3440-
// having the executable separate from the scratch directory allows the recipes to
3441-
// `remove_dir_all(scratch)` without running into permission denied issues because
3442-
// the executable is not under the `scratch/` directory.
3449+
// having the executable separate from the output artifacts directory allows the recipes to
3450+
// `remove_dir_all($TMPDIR)` without running into permission denied issues because
3451+
// the executable is not under the `rmake_out/` directory.
34433452
//
3444-
// This setup diverges from legacy Makefile run-make tests.
3453+
// This setup intentionally diverges from legacy Makefile run-make tests.
34453454
let base_dir = cwd.join(self.output_base_name());
34463455
if base_dir.exists() {
34473456
self.aggressive_rm_rf(&base_dir).unwrap();

src/tools/run-make-support/src/lib.rs

+70-12
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,23 @@ pub fn dynamic_lib_name(name: &str) -> String {
123123
// ```
124124
assert!(!name.contains(char::is_whitespace), "dynamic library name cannot contain whitespace");
125125

126+
let extension = dynamic_lib_extension();
126127
if is_darwin() {
127-
format!("lib{name}.dylib")
128+
format!("lib{name}.{extension}")
128129
} else if is_windows() {
129-
format!("{name}.dll")
130+
format!("{name}.{extension}")
130131
} else {
131-
format!("lib{name}.so")
132+
format!("lib{name}.{extension}")
133+
}
134+
}
135+
136+
pub fn dynamic_lib_extension() -> &'static str {
137+
if is_darwin() {
138+
"dylib"
139+
} else if is_windows() {
140+
"dll"
141+
} else {
142+
"so"
132143
}
133144
}
134145

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

163+
fn ar<P: AsRef<str>, P2: AsRef<str>>(obj_path: P, lib_path: P2, caller_line_number: u32) {
164+
let mut ar = Command::new(env::var("AR").unwrap());
165+
ar.current_dir(tmp_dir()).arg("crus").arg(lib_path.as_ref()).arg(obj_path.as_ref());
166+
let output = ar.output().unwrap();
167+
if !output.status.success() {
168+
handle_failed_output(&ar, output, caller_line_number);
169+
}
170+
}
171+
172+
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
173+
#[track_caller]
174+
pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
175+
let caller_location = std::panic::Location::caller();
176+
let caller_line_number = caller_location.line();
177+
178+
let obj_file = format!("{lib_name}.o");
179+
let src = format!("{lib_name}.c");
180+
let lib_name = if is_msvc() {
181+
let lib_path = format!("lib{lib_name}.lib");
182+
// First compiling `.c` to `.o`.
183+
cc().arg("-c").out_exe(lib_name).input(src).run();
184+
// Generating `.lib` from `.o`.
185+
let mut msvc_lib = Command::new(env::var("MSVC_LIB_PATH").unwrap());
186+
msvc_lib
187+
.current_dir(tmp_dir())
188+
.arg("-nologo")
189+
.arg(&format!("-out:{}", cygpath_windows(&lib_path)))
190+
.arg(&obj_file);
191+
let output = msvc_lib.output().unwrap();
192+
if !output.status.success() {
193+
handle_failed_output(&msvc_lib, output, caller_line_number);
194+
}
195+
lib_path
196+
} else {
197+
let lib_path = format!("lib{lib_name}.a");
198+
// First compiling `.c` to `.o`.
199+
cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run();
200+
// Generating `.a` from `.o`.
201+
ar(obj_file, &lib_path, caller_line_number);
202+
lib_path
203+
};
204+
tmp_dir().join(lib_name)
205+
}
206+
152207
/// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
153208
/// available on the platform!
154209
#[track_caller]
@@ -249,16 +304,13 @@ pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
249304
}
250305

251306
let dir2 = dir2.as_ref();
252-
for entry in fs::read_dir(dir1).unwrap() {
253-
let entry = entry.unwrap();
254-
let entry_name = entry.file_name();
255-
let path = entry.path();
256-
257-
if path.is_dir() {
258-
recursive_diff(&path, &dir2.join(entry_name));
307+
read_dir(dir1, |entry_path| {
308+
let entry_name = entry_path.file_name().unwrap();
309+
if entry_path.is_dir() {
310+
recursive_diff(&entry_path, &dir2.join(entry_name));
259311
} else {
260312
let path2 = dir2.join(entry_name);
261-
let file1 = read_file(&path);
313+
let file1 = read_file(&entry_path);
262314
let file2 = read_file(&path2);
263315

264316
// We don't use `assert_eq!` because they are `Vec<u8>`, so not great for display.
@@ -267,10 +319,16 @@ pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
267319
assert!(
268320
file1 == file2,
269321
"`{}` and `{}` have different content",
270-
path.display(),
322+
entry_path.display(),
271323
path2.display(),
272324
);
273325
}
326+
});
327+
}
328+
329+
pub fn read_dir<F: Fn(&Path)>(dir: impl AsRef<Path>, callback: F) {
330+
for entry in fs::read_dir(dir).unwrap() {
331+
callback(&entry.unwrap().path());
274332
}
275333
}
276334

src/tools/run-make-support/src/rustc.rs

+5
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,11 @@ impl Rustc {
190190
self
191191
}
192192

193+
pub fn extra_filename(&mut self, extra: &str) -> &mut Self {
194+
self.cmd.arg(format!("-Cextra-filename={extra}"));
195+
self
196+
}
197+
193198
/// Specify a stdin input
194199
pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
195200
self.stdin = Some(input.as_ref().to_vec().into_boxed_slice());

src/tools/tidy/src/allowed_run_make_makefiles.txt

-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ run-make/bare-outfile/Makefile
66
run-make/branch-protection-check-IBT/Makefile
77
run-make/c-dynamic-dylib/Makefile
88
run-make/c-dynamic-rlib/Makefile
9-
run-make/c-link-to-rust-dylib/Makefile
109
run-make/c-static-dylib/Makefile
1110
run-make/c-static-rlib/Makefile
1211
run-make/c-unwind-abi-catch-lib-panic/Makefile
@@ -86,7 +85,6 @@ run-make/issue-107094/Makefile
8685
run-make/issue-10971-temps-dir/Makefile
8786
run-make/issue-109934-lto-debuginfo/Makefile
8887
run-make/issue-14698/Makefile
89-
run-make/issue-15460/Makefile
9088
run-make/issue-18943/Makefile
9189
run-make/issue-20626/Makefile
9290
run-make/issue-22131/Makefile

tests/run-make/c-link-to-rust-dylib/Makefile

-21
This file was deleted.

0 commit comments

Comments
 (0)