Skip to content

Commit

Permalink
Auto merge of #125902 - workingjubilee:rollup-f8x6iif, r=workingjubilee
Browse files Browse the repository at this point in the history
Rollup of 6 pull requests

Successful merges:

 - #121062 (Change f32::midpoint to upcast to f64)
 - #125808 (Migrate `run-make/c-link-to-rust-dylib` to `rmake.rs`)
 - #125884 (Implement feature `integer_sign_cast`)
 - #125890 (Improve compiletest expected/not found formatting)
 - #125896 (compiletest: fix outdated rmake.rs comment)
 - #125898 (typo: depending from -> on)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jun 2, 2024
2 parents a6416d8 + 72ea7e9 commit 032af18
Show file tree
Hide file tree
Showing 13 changed files with 218 additions and 69 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
24 changes: 24 additions & 0 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,30 @@ macro_rules! int_impl {
(self as $UnsignedT).trailing_ones()
}

/// Returns the bit pattern of `self` reinterpreted as an unsigned integer of the same size.
///
/// This produces the same result as an `as` cast, but ensures that the bit-width remains
/// the same.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(integer_sign_cast)]
///
#[doc = concat!("let n = -1", stringify!($SelfT), ";")]
///
#[doc = concat!("assert_eq!(n.cast_unsigned(), ", stringify!($UnsignedT), "::MAX);")]
/// ```
#[unstable(feature = "integer_sign_cast", issue = "125882")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
pub const fn cast_unsigned(self) -> $UnsignedT {
self as $UnsignedT
}

/// Shifts the bits to the left by a specified amount, `n`,
/// wrapping the truncated bits to the end of the resulting integer.
///
Expand Down
24 changes: 24 additions & 0 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,30 @@ macro_rules! uint_impl {
(!self).trailing_zeros()
}

/// Returns the bit pattern of `self` reinterpreted as a signed integer of the same size.
///
/// This produces the same result as an `as` cast, but ensures that the bit-width remains
/// the same.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(integer_sign_cast)]
///
#[doc = concat!("let n = ", stringify!($SelfT), "::MAX;")]
///
#[doc = concat!("assert_eq!(n.cast_signed(), -1", stringify!($SignedT), ");")]
/// ```
#[unstable(feature = "integer_sign_cast", issue = "125882")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
pub const fn cast_signed(self) -> $SignedT {
self as $SignedT
}

/// Shifts the bits to the left by a specified amount, `n`,
/// wrapping the truncated bits to the end of the resulting integer.
///
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/str/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ pub unsafe trait ReverseSearcher<'a>: Searcher<'a> {
///
/// `(&str)::Searcher` is not a `DoubleEndedSearcher` because
/// the pattern `"aa"` in the haystack `"aaa"` matches as either
/// `"[aa]a"` or `"a[aa]"`, depending from which side it is searched.
/// `"[aa]a"` or `"a[aa]"`, depending on which side it is searched.
pub trait DoubleEndedSearcher<'a>: ReverseSearcher<'a> {}

/////////////////////////////////////////////////////////////////////////////
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
);
2 changes: 1 addition & 1 deletion library/std/src/sys/thread_local/fast_local/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Thread local support for platforms with native TLS.
//!
//! To achieve the best performance, we choose from four different types for
//! the TLS variable, depending from the method of initialization used (`const`
//! the TLS variable, depending on the method of initialization used (`const`
//! or lazy) and the drop requirements of the stored type:
//!
//! | | `Drop` | `!Drop` |
Expand Down
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
28 changes: 18 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 @@ -3435,13 +3443,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
38 changes: 26 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 Down Expand Up @@ -249,16 +260,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 +275,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
1 change: 0 additions & 1 deletion 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
21 changes: 0 additions & 21 deletions tests/run-make/c-link-to-rust-dylib/Makefile

This file was deleted.

Loading

0 comments on commit 032af18

Please sign in to comment.