Reputation: 170
I'm trying to translate some of my C++ code into Rust and came across the following problem. The code is simplified to a (hopefully) minimal not-working example. In the end it is supposed to work with all unsigned integer types, but for this example it just needs to implement the PartialOrd
trait.
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
#![feature(const_trait_impl)]
const fn foo<T>(n: T, k: T) -> T
where
T: Sized,
T: Copy,
T: ~const core::marker::Destruct,
T: ~const std::cmp::PartialOrd,
{
if n < k {
n
} else {
k
}
}
Fails to compile with the following error message:
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
13 | if n < k {
| ^
If I replace the arguments n
and k
with references, it compiles. Turns out, the functions in the PartialOrd
are also implemented using references. So from my understanding, the expression 2 < 4
will call the le
function with references. For performance reasons, I doubt that's what's happening, though.
It's actually two questions that I'm asking:
PartialOrd
using references while Ord
uses values (at least for min
and max
, but not for cmp
)?Upvotes: 1
Views: 121
Reputation: 580
#![feature(const_refs_to_cell)]
makes it compile.min
and max
take Self
because they return one of the two arguments as Self
. Other methods in Ord
and PartialOrd
else returns a bool
or an Ordering
so they can take by reference. if min
and max
they took by reference the signature would be fn max<'a>(&'a self, other: &'a Self) -> &'a Self
which you "get for free" because there is a impl<A> Ord for &A where A: Ord
.Upvotes: 2