pessimize 3.0.2

More efficient Rust compiler optimization barriers
Documentation
# There are two kinds of continuous integration jobs in this project:
#
# - Every code submission or master push passes continuous integration on the
#   minimal supported Rust version and the current stable Rust version.
# - Two times a month, a scheduled job makes sure that the code remains
#   compatible and lint-free on upcoming Rust toolchains (beta and nightly).

name: Continuous Integration

on:
  push:
  pull_request:
  schedule:
    - cron: '0 0 12/15 * *'

# Cancel existing jobs on new pushes to the same branch
concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

env:
  CARGO_INCREMENTAL: 0
  RUSTFLAGS: -D warnings
  RUSTDOCFLAGS: -D warnings
  MINIMAL_RUST: 1.89.0  # Minimal Supported Rust Version

jobs:
  # Workaround for github CI dropping env var expansion in matrix strategy
  matrix_vars:
    runs-on: ubuntu-latest
    outputs:
      MINIMAL_RUST: ${{ env.MINIMAL_RUST }}
    steps:
      - name: Forward env var to output
        run: echo "MINIMAL_RUST=${{ env.MINIMAL_RUST }}" >> $GITHUB_OUTPUT


  # Formatting and dependency checking doesn't depend on configuration, and we
  # only care about the formatting rules of the latest supported Rust version
  format-machete:
    # Don't run CI twice when a PR is created from a branch internal to the repo
    if: github.event_name == 'push' || github.event_name == 'schedule' || github.event.pull_request.head.repo.full_name != github.repository

    runs-on: ubuntu-22.04

    steps:
      - name: Checkout sources
        uses: actions/checkout@v6

      - name: Set up stable toolchain
        if: github.event_name != 'schedule'
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          components: rustfmt

      - name: Set up nightly toolchain
        if: github.event_name == 'schedule'
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: nightly
          components: rustfmt

      - name: Check code formatting
        run: cargo fmt --all --check

      - name: Set up cargo-binstall
        run: curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash

      - name: Look for unused dependencies with cargo-machete
        run: |
          # FIXME: --force used as a workaround for https://github.com/Swatinem/rust-cache/issues/204
          cargo binstall -y --force cargo-machete
          cargo machete


  # Lints should cover all cfg code paths
  #
  # We do not check lints for the MSRV, only for the latest supported Rust
  # stable compiler release and for the nightly compiler (the later is
  # unfortunate as it means CI will randomly break, but we need it since we have
  # nightly-specific code paths).
  #
  # Native x86_64 compilation...
  lints-native:
    if: github.event_name == 'push' || github.event_name == 'schedule' || github.event.pull_request.head.repo.full_name != github.repository
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        toolchain:
          - stable
          - nightly
        cargo-flags:
          - '--no-default-features'
          - '--no-default-features --features=alloc'
          - ''  # --features=std
          - '--features=safe_arch'
        rust-flags:
          - ''
          - '-C target-feature=+avx'
          - '-C target-feature=+avx -C target-feature=+avx2'
          - '-C target-feature=+avx -C target-feature=+avx2 -C target-feature=+avx512f'
          - '-C target-feature=+avx -C target-feature=+avx2 -C target-feature=+avx512f -C target-feature=+avx512bw -C target-feature=+avx512vl'
          - '-C target-feature=+avx -C target-feature=+avx2 -C target-feature=+avx512f -C target-feature=+avx512bw -C target-feature=+avx512vl -C target-feature=+avx512bf16'
        exclude:
          - toolchain: stable
            rust-flags: '-C target-feature=+avx -C target-feature=+avx2 -C target-feature=+avx512f'
          - toolchain: stable
            rust-flags: '-C target-feature=+avx -C target-feature=+avx2 -C target-feature=+avx512f -C target-feature=+avx512bw -C target-feature=+avx512vl'
          - toolchain: stable
            rust-flags: '-C target-feature=+avx -C target-feature=+avx2 -C target-feature=+avx512f -C target-feature=+avx512bw -C target-feature=+avx512vl -C target-feature=+avx512bf16'
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
      - name: Check lints
        uses: ./.github/actions/lints
        with:
          toolchain: ${{ matrix.toolchain }}
          cargo-flags: ${{ matrix.cargo-flags }}
          rust-flags: ${{ matrix.rust-flags }}
  #
  # ARMv7 cross-compilation
  lints-arm:
    if: github.event_name == 'push' || github.event_name == 'schedule' || github.event.pull_request.head.repo.full_name != github.repository
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        toolchain:
          - stable
          - nightly
        cargo-flags:
          - '--no-default-features'
          - '--no-default-features --features=alloc'
          - ''  # --features=std
          - '--features=safe_arch'
        rust-flags:
          - ''
          - '-C target-feature=-vfp2'
          - '-C target-feature=+vfp2'
          - '-C target-feature=+vfp2 -C target-feature=+d32'
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
      - name: Check lints
        uses: ./.github/actions/lints
        with:
          toolchain: ${{ matrix.toolchain }}
          cargo-flags: ${{ matrix.cargo-flags }}
          rust-flags: ${{ matrix.rust-flags }}
          cross-target-apt: 'arm-linux-gnueabi'
          cross-target-rust: 'arm-unknown-linux-gnueabi'
  #
  # AArch64 cross-compilation
  lints-aarch64:
    if: github.event_name == 'push' || github.event_name == 'schedule' || github.event.pull_request.head.repo.full_name != github.repository
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        toolchain:
          - stable
          - nightly
        cargo-flags:
          - '--no-default-features'
          - '--no-default-features --features=alloc'
          - ''  # --features=std
          - '--features=safe_arch'
        rust-flags:
          - ''
          - '-C target-feature=-neon'
          - '-C target-feature=+neon'
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
      - name: Check lints
        uses: ./.github/actions/lints
        with:
          toolchain: ${{ matrix.toolchain }}
          cargo-flags: ${{ matrix.cargo-flags }}
          rust-flags: ${{ matrix.rust-flags }}
          cross-target-apt: 'aarch64-linux-gnu'
          cross-target-rust: 'aarch64-unknown-linux-gnu'
  #
  # i686 cross-compilation
  lints-i686:
    if: github.event_name == 'push' || github.event_name == 'schedule' || github.event.pull_request.head.repo.full_name != github.repository
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        toolchain:
          - stable
          - nightly
        cargo-flags:
          - '--no-default-features'
          - '--no-default-features --features=alloc'
          - ''  # --features=std
          - '--features=safe_arch'
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
      - name: Check lints
        uses: ./.github/actions/lints
        with:
          toolchain: ${{ matrix.toolchain }}
          cargo-flags: ${{ matrix.cargo-flags }}
          cross-target-apt: 'i686-linux-gnu'
          cross-target-rust: 'i686-unknown-linux-gnu'
  #
  # RISC-V 64-bit cross-compilation
  # FIXME: I'd also like to test riscv32 but ubuntu doesn't provide a cross-compiler
  lints-riscv64:
    if: github.event_name == 'push' || github.event_name == 'schedule' || github.event.pull_request.head.repo.full_name != github.repository
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        toolchain:
          - stable
          - nightly
        cargo-flags:
          - '--no-default-features'
          - '--no-default-features --features=alloc'
          - ''  # --features=std
          - '--features=safe_arch'
        rust-flags:
          - ''
          - '-C target-feature=-f -C target-feature=-d'
          - '-C target-feature=+f -C target-feature=-d'
          - '-C target-feature=+f -C target-feature=+d'
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
      - name: Check lints
        uses: ./.github/actions/lints
        with:
          toolchain: ${{ matrix.toolchain }}
          cargo-flags: ${{ matrix.cargo-flags }}
          rust-flags: ${{ matrix.rust-flags }}
          cross-target-apt: 'riscv64-linux-gnu'
          cross-target-rust: 'riscv64gc-unknown-linux-gnu'


  # Run the tests on all supported OSes and Rust versions (main CI)
  #
  # FIXME: It would be nice to also run the tests for cross-compiled targets
  #        using some kind of emulation layer
  test-native:
    # Don't run CI twice when a PR is created from a branch internal to the repo
    if: github.event_name == 'push' || github.event_name == 'schedule' || github.event.pull_request.head.repo.full_name != github.repository

    needs: matrix_vars

    runs-on: ubuntu-22.04

    strategy:
      matrix:
        toolchain:
          - ${{ needs.matrix_vars.outputs.MINIMAL_RUST }}
          - stable
          - nightly
        cargo-flags:
          # Stable configurations
          - '--no-default-features'
          - '--no-default-features --features=alloc'
          - ''  # --features=std
          - '--features=safe_arch'
          # Nightly configuration = stable configuration + nightly feature
          - '--no-default-features --features=nightly'
          - '--no-default-features --features=alloc,nightly'
          - '--features=nightly'
          - '--features=safe_arch,nightly'
        rust-flags:
          - ""
          - "-C target-cpu=native"
        exclude:
          - toolchain: nightly
            cargo-flags: '--no-default-features'
          - toolchain: nightly
            cargo-flags: '--no-default-features --features=alloc'
          - toolchain: nightly
            cargo-flags: ''
          - toolchain: nightly
            cargo-flags: '--features=safe_arch'
          - toolchain: stable
            cargo-flags: '--no-default-features --features=nightly'
          - toolchain: stable
            cargo-flags: '--no-default-features --features=alloc,nightly'
          - toolchain: stable
            cargo-flags: '--features=nightly'
          - toolchain: stable
            cargo-flags: '--features=safe_arch,nightly'
          - toolchain: ${{ needs.matrix_vars.outputs.MINIMAL_RUST }}
            cargo-flags: '--no-default-features --features=nightly'
          - toolchain: ${{ needs.matrix_vars.outputs.MINIMAL_RUST }}
            cargo-flags: '--no-default-features --features=alloc,nightly'
          - toolchain: ${{ needs.matrix_vars.outputs.MINIMAL_RUST }}
            cargo-flags: '--features=nightly'
          - toolchain: ${{ needs.matrix_vars.outputs.MINIMAL_RUST }}
            cargo-flags: '--features=safe_arch,nightly'

    env:
      RUSTFLAGS: "${{ matrix.rust-flags }}"

    steps:
      - name: Checkout sources
        uses: actions/checkout@v6

      # Cargo doesn't know when to rebuild a target-cpu=native cache when it's
      # migrated across machines, so a CI node must not be exposed to the target
      # directory generated by another CI node in target-cpu=native mode.
      - name: Avoid abusive caching with target-cpu=native
        run: |
            if [[ ${RUSTFLAGS} =~ '-C target-cpu=native' ]]; then
                cp /proc/cpuinfo cpuinfo.key
            else
                echo "Generic x86_64" >cpuinfo.key
            fi

      - name: Set up toolchain
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: ${{ matrix.toolchain }}
          cache-key: ${{ hashFiles('cpuinfo.key') }}

      - name: Run tests
        run: cargo test --workspace ${{ matrix.cargo-flags }}