I ran into a weird situation earlier. I wrote:
if rand::random() < self.food_chance {...}
(self.food_chance
is of type f32
)
and I got a type inferencing error:
|
71 | if rand::random() < self.food_chance {
| ^^^^^^^^^^^^ cannot infer type for `T`
However this code compiles
if self.food_chance > rand::random() {...}
And I'm left wondering. Is there a reason for this behaviour? Is it even intended behaviour?
I know a little bit about type inferencing theory, and I know that most of the algorithms are agnostic to lhs/rhs, so I'm tempted to think this is expected behaviour rather than straight up a bug.
I tried searching around, but I never got anything close to this.
That's basically because Rust can never infer the type of the receiver. The type of the receiver must be known to perform method lookup, and since
rand::random() < self.food_chance
is equivalent to
std::cmp::PartialOrd::lt(&rand::random(), &self.food_chance);
the receiver is the left-hand operand.
In the expression
self.food_chance > rand::random()
on the other hand, the receiver is known, so Rust can perform method lookup. It will only find a single implementation for f32
as the receiver, namely PartialOrd<f32>
, which then in turn determines the type of the right-hand side. If there were implementations for different right-hand side types, Rust would not be able to infer the type in that case either.
To understand why Rust can't infer the receiver, take a look at how Rust's method lookup process works. The first step is to build a list of candidate types based on the type of the receiver. This obvious only works when you already know the type of the receiver.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With