about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2025-02-02 16:13:07 +0100
committerRalf Jung <post@ralfj.de>2025-02-02 16:13:07 +0100
commitf034a1544193a91fc03ced4a047fe8a3fa857b81 (patch)
treeb29ab119ebbd418e0a932c83dfe488f0b3ce9f35 /src
parentbf69458973ae5fc249ec06406669f4e1f547d3d0 (diff)
parent6dd75f0d6802f56564f5f9c947a85ded286d3986 (diff)
downloadrust-f034a1544193a91fc03ced4a047fe8a3fa857b81.tar.gz
rust-f034a1544193a91fc03ced4a047fe8a3fa857b81.zip
Merge from rustc
Diffstat (limited to 'src')
-rw-r--r--src/ci/github-actions/jobs.yml4
-rwxr-xr-xsrc/ci/scripts/free-disk-space.sh94
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs4
-rw-r--r--src/tools/miri/src/machine.rs13
-rw-r--r--src/tools/miri/src/operator.rs7
-rw-r--r--src/tools/miri/tests/pass/float.rs28
6 files changed, 113 insertions, 37 deletions
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index 9af88709625..37299a5a76b 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -5,7 +5,7 @@ runners:
     env: { }
 
   - &job-linux-4c
-    os: ubuntu-22.04
+    os: ubuntu-24.04
     # Free some disk space to avoid running out of space during the build.
     free_disk: true
     <<: *base-job
@@ -50,7 +50,7 @@ runners:
   - &job-aarch64-linux
     # Free some disk space to avoid running out of space during the build.
     free_disk: true
-    os: ubuntu-22.04-arm
+    os: ubuntu-24.04-arm
 
   - &job-aarch64-linux-8c
     os: ubuntu-22.04-arm64-8core-32gb
diff --git a/src/ci/scripts/free-disk-space.sh b/src/ci/scripts/free-disk-space.sh
index 4a7dad0090b..8850e168145 100755
--- a/src/ci/scripts/free-disk-space.sh
+++ b/src/ci/scripts/free-disk-space.sh
@@ -1,8 +1,19 @@
 #!/bin/bash
+set -euo pipefail
 
 # Free disk space on Linux GitHub action runners
 # Script inspired by https://github.com/jlumbroso/free-disk-space
 
+isX86() {
+    local arch
+    arch=$(uname -m)
+    if [ "$arch" = "x86_64" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
 # print a line of the specified character
 printSeparationLine() {
     for ((i = 0; i < 80; i++)); do
@@ -14,11 +25,15 @@ printSeparationLine() {
 # compute available space
 # REF: https://unix.stackexchange.com/a/42049/60849
 # REF: https://stackoverflow.com/a/450821/408734
-getAvailableSpace() { echo $(df -a | awk 'NR > 1 {avail+=$4} END {print avail}'); }
+getAvailableSpace() {
+    df -a | awk 'NR > 1 {avail+=$4} END {print avail}'
+}
 
 # make Kb human readable (assume the input is Kb)
 # REF: https://unix.stackexchange.com/a/44087/60849
-formatByteCount() { echo $(numfmt --to=iec-i --suffix=B --padding=7 $1'000'); }
+formatByteCount() {
+    numfmt --to=iec-i --suffix=B --padding=7 "$1"'000'
+}
 
 # macro to output saved space
 printSavedSpace() {
@@ -58,11 +73,27 @@ removeDir() {
     dir=${1}
 
     local before
-    before=$(getAvailableSpace)
+    if [ ! -d "$dir" ]; then
+        echo "::warning::Directory $dir does not exist, skipping."
+    else
+        before=$(getAvailableSpace)
+        sudo rm -rf "$dir"
+        printSavedSpace "$before" "Removed $dir"
+    fi
+}
+
+removeUnusedDirectories() {
+    local dirs_to_remove=(
+        "/usr/local/lib/android"
+        "/usr/share/dotnet"
 
-    sudo rm -rf "$dir" || true
+        # Haskell runtime
+        "/usr/local/.ghcup"
+    )
 
-    printSavedSpace "$before" "$dir"
+    for dir in "${dirs_to_remove[@]}"; do
+        removeDir "$dir"
+    done
 }
 
 execAndMeasureSpaceChange() {
@@ -79,21 +110,29 @@ execAndMeasureSpaceChange() {
 # Remove large packages
 # REF: https://github.com/apache/flink/blob/master/tools/azure-pipelines/free_disk_space.sh
 cleanPackages() {
-    sudo apt-get -qq remove -y --fix-missing \
-        '^aspnetcore-.*'       \
-        '^dotnet-.*'           \
-        '^llvm-.*'             \
-        'php.*'                \
-        '^mongodb-.*'          \
-        '^mysql-.*'            \
-        'azure-cli'            \
-        'google-chrome-stable' \
-        'firefox'              \
-        'powershell'           \
-        'mono-devel'           \
-        'libgl1-mesa-dri'      \
-        'google-cloud-sdk'     \
-        'google-cloud-cli'
+    local packages=(
+        '^aspnetcore-.*'
+        '^dotnet-.*'
+        '^llvm-.*'
+        '^mongodb-.*'
+        '^mysql-.*'
+        'azure-cli'
+        'firefox'
+        'libgl1-mesa-dri'
+        'mono-devel'
+        'php.*'
+    )
+
+    if isX86; then
+        packages+=(
+            'google-chrome-stable'
+            'google-cloud-cli'
+            'google-cloud-sdk'
+            'powershell'
+        )
+    fi
+
+    sudo apt-get -qq remove -y --fix-missing "${packages[@]}"
 
     sudo apt-get autoremove -y || echo "::warning::The command [sudo apt-get autoremove -y] failed"
     sudo apt-get clean || echo "::warning::The command [sudo apt-get clean] failed failed"
@@ -101,9 +140,9 @@ cleanPackages() {
 
 # Remove Docker images
 cleanDocker() {
-    echo "Removing the following docker images:"
+    echo "=> Removing the following docker images:"
     sudo docker image ls
-    echo "Removing docker images..."
+    echo "=> Removing docker images..."
     sudo docker image prune --all --force || true
 }
 
@@ -121,17 +160,12 @@ AVAILABLE_INITIAL=$(getAvailableSpace)
 printDF "BEFORE CLEAN-UP:"
 echo ""
 
-removeDir /usr/local/lib/android
-removeDir /usr/share/dotnet
-
-# Haskell runtime
-removeDir /opt/ghc
-removeDir /usr/local/.ghcup
-
-execAndMeasureSpaceChange cleanPackages "Large misc. packages"
+execAndMeasureSpaceChange cleanPackages "Unused packages"
 execAndMeasureSpaceChange cleanDocker "Docker images"
 execAndMeasureSpaceChange cleanSwap "Swap storage"
 
+removeUnusedDirectories
+
 # Output saved space statistic
 echo ""
 printDF "AFTER CLEAN-UP:"
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 287bdc9a6fd..0aaef91e48a 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -116,6 +116,7 @@ fn check_rvalue<'tcx>(
         Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv),
         Rvalue::Repeat(operand, _)
         | Rvalue::Use(operand)
+        | Rvalue::WrapUnsafeBinder(operand, _)
         | Rvalue::Cast(
             CastKind::PointerWithExposedProvenance
             | CastKind::IntToInt
@@ -289,7 +290,8 @@ fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &B
             | ProjectionElem::Downcast(..)
             | ProjectionElem::Subslice { .. }
             | ProjectionElem::Subtype(_)
-            | ProjectionElem::Index(_) => {},
+            | ProjectionElem::Index(_)
+            | ProjectionElem::UnwrapUnsafeBinder(_) => {},
         }
     }
 
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index ff4b0ac3827..4735db48e81 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -11,6 +11,7 @@ use std::{fmt, process};
 use rand::rngs::StdRng;
 use rand::{Rng, SeedableRng};
 use rustc_abi::{Align, ExternAbi, Size};
+use rustc_apfloat::{Float, FloatConvert};
 use rustc_attr_parsing::InlineAttr;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 #[allow(unused)]
@@ -1132,20 +1133,24 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
     }
 
     #[inline(always)]
-    fn generate_nan<
-        F1: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F2>,
-        F2: rustc_apfloat::Float,
-    >(
+    fn generate_nan<F1: Float + FloatConvert<F2>, F2: Float>(
         ecx: &InterpCx<'tcx, Self>,
         inputs: &[F1],
     ) -> F2 {
         ecx.generate_nan(inputs)
     }
 
+    #[inline(always)]
+    fn equal_float_min_max<F: Float>(ecx: &MiriInterpCx<'tcx>, a: F, b: F) -> F {
+        ecx.equal_float_min_max(a, b)
+    }
+
+    #[inline(always)]
     fn ub_checks(ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool> {
         interp_ok(ecx.tcx.sess.ub_checks())
     }
 
+    #[inline(always)]
     fn thread_local_static_pointer(
         ecx: &mut MiriInterpCx<'tcx>,
         def_id: DefId,
diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs
index 124b2a765a9..a3c063d0f37 100644
--- a/src/tools/miri/src/operator.rs
+++ b/src/tools/miri/src/operator.rs
@@ -115,4 +115,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             nan
         }
     }
+
+    fn equal_float_min_max<F: Float>(&self, a: F, b: F) -> F {
+        let this = self.eval_context_ref();
+        // Return one side non-deterministically.
+        let mut rand = this.machine.rng.borrow_mut();
+        if rand.gen() { a } else { b }
+    }
 }
diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs
index 4de315e3589..2f4f64b1aa8 100644
--- a/src/tools/miri/tests/pass/float.rs
+++ b/src/tools/miri/tests/pass/float.rs
@@ -31,6 +31,7 @@ fn main() {
     test_fast();
     test_algebraic();
     test_fmuladd();
+    test_min_max_nondet();
 }
 
 trait Float: Copy + PartialEq + Debug {
@@ -1211,3 +1212,30 @@ fn test_fmuladd() {
     test_operations_f32(0.1, 0.2, 0.3);
     test_operations_f64(1.1, 1.2, 1.3);
 }
+
+/// `min` and `max` on equal arguments are non-deterministic.
+fn test_min_max_nondet() {
+    /// Ensure that if we call the closure often enough, we see both `true` and `false.`
+    #[track_caller]
+    fn ensure_both(f: impl Fn() -> bool) {
+        let rounds = 16;
+        let first = f();
+        for _ in 1..rounds {
+            if f() != first {
+                // We saw two different values!
+                return;
+            }
+        }
+        // We saw the same thing N times.
+        panic!("expected non-determinism, got {rounds} times the same result: {first:?}");
+    }
+
+    ensure_both(|| f16::min(0.0, -0.0).is_sign_positive());
+    ensure_both(|| f16::max(0.0, -0.0).is_sign_positive());
+    ensure_both(|| f32::min(0.0, -0.0).is_sign_positive());
+    ensure_both(|| f32::max(0.0, -0.0).is_sign_positive());
+    ensure_both(|| f64::min(0.0, -0.0).is_sign_positive());
+    ensure_both(|| f64::max(0.0, -0.0).is_sign_positive());
+    ensure_both(|| f128::min(0.0, -0.0).is_sign_positive());
+    ensure_both(|| f128::max(0.0, -0.0).is_sign_positive());
+}