0

I have a struct that I want to use it as a key in BTreeMap, so I implement PartialEq, Eq, PartialOrd and Ord. The last causes a problem as there is an unsafe clamp trait method.

I implement it this way:

use std::cmp::Ordering;

#[derive(Debug, Eq, Copy, Clone)]
struct Baz(usize);

impl PartialEq for Baz {
    fn eq(&self, other: &Self) -> bool {
        self.0.eq(&other.0)
    }

    fn ne(&self, other: &Self) -> bool {
        self.0.ne(&other.0)
    }
}

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

    fn lt(&self, other: &Self) -> bool {
        self.0.lt(&other.0)
    }

    fn le(&self, other: &Self) -> bool {
        self.0.le(&other.0)
    }

    fn gt(&self, other: &Self) -> bool {
        self.0.gt(&other.0)
    }

    fn ge(&self, other: &Self) -> bool {
        self.0.ge(&other.0)
    }
}

impl Ord for Baz {
    fn cmp(&self, other: &Self) -> Ordering {
        self.0.cmp(&other.0)
    }

    fn max(self, other: Self) -> Self
    where
        Self: Sized,
    {
        Self(self.0.max(other.0))
    }

    fn min(self, other: Self) -> Self
    where
        Self: Sized,
    {
        Self(self.0.min(other.0))
    }

    fn clamp(self, min: Self, max: Self) -> Self
    where
        Self: Sized,
    {
        Self(self.0.clamp(min.0, max.0))
    }
}

fn main() {
    Baz(1);
}

Playground

As far as I know, clamp for integers is safe and should work just fine, but Rust gives me the error

error[E0658]: use of unstable library feature 'clamp'
  --> src/main.rs:57:5
   |
57 | /     fn clamp(self, min: Self, max: Self) -> Self
58 | |     where
59 | |         Self: Sized,
60 | |     {
61 | |         Self(self.0.clamp(min.0, max.0))
62 | |     }
   | |_____^
   |
   = note: for more information, see https://github.com/rust-lang/rust/issues/44095

error[E0658]: use of unstable library feature 'clamp'
  --> src/main.rs:61:21
   |
61 |         Self(self.0.clamp(min.0, max.0))
   |                     ^^^^^
   |
   = note: for more information, see https://github.com/rust-lang/rust/issues/44095

How can I solve this? I'm using Rust 1.41.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • It's hard to answer your question because it doesn't include a [MRE]. We can't tell what crates (and their versions), types, traits, fields, etc. are present in the code. It would make it easier for us to help you if you try to reproduce your error on the [Rust Playground](https://play.rust-lang.org) if possible, otherwise in a brand new Cargo project, then [edit] your question to include the additional info. There are [Rust-specific MRE tips](//stackoverflow.com/tags/rust/info) you can use to reduce your original code for posting here. Thanks! – Shepmaster Mar 09 '20 at 20:46
  • *an unsafe `clamp` trait method* — it is not `unsafe`, and it's unclear why you think it is. – Shepmaster Mar 09 '20 at 20:51
  • Added playground link as you requested. – Alexander Vtyurin Mar 09 '20 at 20:52

1 Answers1

1

As far as I know, clamp for integers is safe and should work just fine, but Rust gives me the error

That's because the Ord::clamp method is unstable — the compiler isn't lying to you. However, that's a method with a default implementation, so you don't need to implement it (and shouldn't, unless you can improve on the default implementation).

Helpfully, there's a section in the documentation for Ord titled How can I implement Ord? which describes exactly what you need to do:

Ord requires that the type also be PartialOrd and Eq (which requires PartialEq).

Then you must define an implementation for cmp(). You may find it useful to use cmp() on your type's fields.

Of special relevance is the fact that Ord can be derived:

This trait can be used with #[derive]. When derived on structs, it will produce a lexicographic ordering based on the top-to-bottom declaration order of the struct's members. When derived on enums, variants are ordered by their top-to-bottom declaration order.

Your entire code can likely be

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
struct Baz(usize);

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366