rust-lang / rust-lang/rust

1.81.0 not panic when running incorrect implementations of Ord

Open
#130,178 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-discussion T-libs
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.
-->

I tried this code by running rustup run 1.81.0 cargo run:

use std::cmp::Ordering;

#[derive(Debug)]
struct BadOrd(i32);

impl PartialEq for BadOrd {
    fn eq(&self, other: &Self) -> bool {
        // Intentionally inconsistent equality
        self.0 % 2 == other.0 % 2
    }
}

impl Eq for BadOrd {}

impl PartialOrd for BadOrd {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        // Violates consistency, transitivity, and duality
        if self.0 % 2 == 0 && other.0 % 2 != 0 {
            Some(Ordering::Less)
        } else if self.0 % 2 != 0 && other.0 % 2 == 0 {
            Some(Ordering::Greater)
        } else if self.0 == other.0 {
            Some(Ordering::Equal)
        } else {
            None
        }
    }
}

impl Ord for BadOrd {
    fn cmp(&self, other: &Self) -> Ordering {
        // Inconsistent with PartialOrd and violates total ordering
        if self.0 < other.0 {
            Ordering::Greater
        } else if self.0 > other.0 {
            Ordering::Less
        } else {
            Ordering::Equal
        }
    }
}

fn main() {
    let mut vec = vec![BadOrd(3), BadOrd(2), BadOrd(4), BadOrd(1)];

    println!("Before sorting: {:?}", vec);

    vec.sort(); // This will likely panic due to inconsistent ordering

    println!("After sorting: {:?}", vec);

    // These assertions will fail, demonstrating incorrect ordering
    assert!(BadOrd(1) < BadOrd(2));
    assert!(BadOrd(2) > BadOrd(1));
    assert!(BadOrd(2) == BadOrd(2));

    println!("All assertions passed!");
}

I expected to see this happen: explanation
The program would panic on the line "vec.sort();" since "the new sort algorithms try to detect incorrect implementations of Ord that prevent them from being able to produce a meaningfully sorted result, and will now panic on such cases rather than returning effectively randomly arranged data.", according to the "New sort implementations" in https://blog.rust-lang.org/2024/09/05/Rust-1.81.0.html.

Instead, this happened: explanation
The program paniced on the line "assert!(BadOrd(1) < BadOrd(2));". Here is the output:

Before sorting: [BadOrd(3), BadOrd(2), BadOrd(4), BadOrd(1)]
After sorting: [BadOrd(2), BadOrd(4), BadOrd(3), BadOrd(1)]
thread 'main' panicked at src/main.rs:53:5:
assertion failed: BadOrd(1) < BadOrd(2)
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

Meta

rustc --version --verbose:

rustc 1.81.0 (eeb90cda1 2024-09-04)
binary: rustc
commit-hash: eeb90cda1969383f56a2637cbd3037bdf598841c
commit-date: 2024-09-04
host: aarch64-apple-darwin
release: 1.81.0
LLVM version: 18.1.7

rustc 1.82.0-beta.2 (c7c49f44a 2024-09-04)
binary: rustc
commit-hash: c7c49f44a7bb561dd9317e14908a1e50fa478ce5
commit-date: 2024-09-04
host: aarch64-apple-darwin
release: 1.82.0-beta.2
LLVM version: 19.1.0

rustc 1.83.0-nightly (c2f74c3f9 2024-09-09)
binary: rustc
commit-hash: c2f74c3f928aeb503f15b4e9ef5778e77f3058b8
commit-date: 2024-09-09
host: aarch64-apple-darwin
release: 1.83.0-nightly
LLVM version: 19.1.0
Backtrace

RUST_BACKTRACE=1 rustup run 1.81.0 cargo run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.16s
     Running `target/debug/new_sort_implementations_in_1_81_0_stable_rust`
Before sorting: [BadOrd(3), BadOrd(2), BadOrd(4), BadOrd(1)]
After sorting: [BadOrd(2), BadOrd(4), BadOrd(3), BadOrd(1)]
thread 'main' panicked at src/main.rs:53:5:
assertion failed: BadOrd(1) < BadOrd(2)
stack backtrace:
   0: rust_begin_unwind
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:665:5
   1: core::panicking::panic_fmt
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/panicking.rs:74:14
   2: core::panicking::panic
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/panicking.rs:148:5
   3: new_sort_implementations_in_1_81_0_stable_rust::main
             at ./src/main.rs:53:5
   4: core::ops::function::FnOnce::call_once
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the report with rustup run 1.81.0 cargo run, starting from src/main.rs around vec.sort() and the assertion at line 53. Compare the observed behavior with the documented Rust 1.81.0 sort changes; done means determining whether this is an implementation bug or an incorrect expectation and documenting a minimal regression case if appropriate.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.