Reputation: 57
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.
Upvotes: 4
Views: 120
Reputation: 601489
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.
Upvotes: 7
Reputation: 359
The >
operator is sugar for a method; the partial_cmp
method of the PartialOrd
trait. The method is called with the left-hand side as the self
argument; this determines which implementation of PartialOrd
is used. Because you could implement the PartialOrd
trait for different types with f32
as the right-hand side type, the implementation of PartialOrd
is only uniquely determined if the type of the left-hand side is known. This implementation of PartialOrd
, in turn, determines the type required from rand::random
.
Upvotes: 3