Reputation: 125
I created a function in a sample Rust project that compares two values of types that implement the PartialOrd
trait, but it isn't compiling:
fn main(){
let x: i32 = 5;
let y: i32 = 6;
dbg!(greater_than(&x, &y));
}
fn greater_than(x: &impl PartialOrd, y: &impl PartialOrd) -> bool{
x > y
}
error[E0308]: mismatched types
--> src/main.rs:8:9
|
7 | fn greater_than(x: &impl PartialOrd, y: &impl PartialOrd) -> bool{
| --------------- --------------- found type parameter
| |
| expected type parameter
8 | x > y
| ^ expected type parameter `impl PartialOrd`, found a different type parameter `impl PartialOrd`
|
= note: expected reference `&impl PartialOrd` (type parameter `impl PartialOrd`)
found reference `&impl PartialOrd` (type parameter `impl PartialOrd`)
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
My understanding is that once in your parameters in your function signature were typed using the impl trait syntax, any type that implement that trait (i32 is meant to implement PartialOrd trait) could be used in the function as an argument. (I have used a different function signature -using trait bounds as shown below- and it worked fine):
fn greater_than<T: PartialOrd>(x: &T, y: &T) -> bool
Upvotes: 2
Views: 107
Reputation: 42592
My understanding is that once in your parameters in your function signature were typed using the impl trait syntax, any type that implement that trait (i32 is meant to implement PartialOrd trait) could be used in the function as an argument.
Well yes, but impl trait
defines no relation between your arguments, so what you've written is essentially
fn greater_than<T: PartialOrd, U: PartialOrd>(x: &T, y: &U) -> bool
So each argument is partially comparable to itself, but there's no implication that they're partially comparable to one another. For all Rust is concerned, you could pass an i32 as first parameter and a String as second, they both impl PartialOrd
.
Upvotes: 5
Reputation: 71545
Each occurrence of impl Trait
gives a new distinct type parameter. For example, x
can be u32
and y
String
. Both implement PartialOrd
, but they still cannot be compared with one another.
What you want cannot be expressed with impl Trait
, since you need to mention the type twice:
fn greater_than<T: PartialOrd>(x: &T, y: &T) -> bool{
x > y
}
Or, to accept even two different types as long as they can be compared:
fn greater_than<T: PartialOrd<U>, U>(x: &T, y: &U) -> bool {
x > y
}
Upvotes: 7