Skip to content

Lint that encourages people to implement PartialOrd in terms of Ord when applicable #10744

Closed
@joseph-gio

Description

@joseph-gio

What it does

When a type manually implements both PartialOrd and Ord, both implementations must agree i.e. behave the same way. Usually, the function bodies of ord and partial_ord are identical, save for wrapping the return expression in Some() for partial_ord. This is unnecessarily repetitive and makes the code more prone to error during refactoring, as one may forget to update one of the implementations. The best way of implementing these traits manually is to implement PartialOrd in terms of Ord, which reduces code duplication and guarantees that they function in the same way.

This lint should not trigger if the bounds on the impl for Ord are more restrictive than the bounds on PartialOrd.

Real-world example: bevyengine/bevy#8529 (comment).

Lint Name

duplicate_manual_partial_ord_impl

Category

style, complexity

Advantage

  • The code is less repetitive.
  • Implementations of PartialOrd and Ord are guaranteed to agree. This is safer for future refactoring, since you can't forget to update one of the two impls.

Drawbacks

Will trigger on code that isn't broken which may be annoying, but following the lint's advice will always (as far as I can tell) make the code more robust.

Example

impl Ord for F {
    fn cmp(&self, other: &Self) -> Ordering {
        match self.a.cmp(&other.b) {
            // .. some complex logic
        }
    }
}

impl PartialOrd for F {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(match self.a.cmp(&other.b) {
            // .. some complex logic
        })
    }
}

Could be written as:

impl Ord for F { /* Unchanged */ }

impl PartialOrd for F {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

Metadata

Metadata

Assignees

Labels

A-lintArea: New lints

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions