Relevant libs:

```
use std::ops::sub;
use either::{Either, Left, Right, for_both};
```

Relevant code:

```
struct Vec2 {
x: f32,
y: f32,
}
```

Here I implement subtraction for Vec2:

```
impl Sub for Vec2 {
type Output = Either<f32, Vec2>;
fn sub(self, rhs: Self) -> Either<f32, Self>{
let result = Vec2 {
x: self.x - rhs.x,
y: self.y - rhs.y
};
match result {
Vec2 { x: 0f32, y: 0f32 } => Left(0f32),
_ => Right(result),
}
}
}
```

I get an error in my main function. Summed up:

```
fn main() {
let u = Vec2 { x: 2f32, y: 1f32 };
let v = Vec2 { x: 1f32, y: 2f32 };
let res = for_both!(u - v, s => s); // The error appears here
// ^ this specifically
println!("u - v: {:#?}", res);
}
```

The error reads

`expected 'f32' found struct 'Vec2'. This is found to be of type 'f32'.`

I think I am understanding this wrong, I just don't really know how to interpret this error message. It kind of left me more confused than I already up. I looked at the docs again but it's just really not making much sense.

If you go to `either::for_both!`

's documentation you can see a `source`

link on the top right. Clicking it will bring you to the source code of the macro, which is just:

```
macro_rules! for_both {
($value:expr, $pattern:pat => $result:expr) => {
match $value {
$crate::Either::Left($pattern) => $result,
$crate::Either::Right($pattern) => $result,
}
};
}
```

So what it does is just being a shorthand for matching an expression you give it (`u - v`

in your case) and for each case match the value inside the `Either::Left`

/`Either::Right`

with the pattern you give it (the first `s`

) and then return the expression you give it at the end (the second `s`

). Notably, since this is a `match`

, the expression returned must have the same type on both sides. In your code however `s`

has type `f32`

in one branch and `Vec2`

in the other, so this is an error.

What you could do however is to write the `println!`

instead of the second `s`

. This way the expression on both branches evaluate to `()`

(i.e. no value, which is what `println!`

returns) and you receive the expected print because in each branch the correct type is known. Rust Playground

1 Like

The macro is pretty simple, and in your example it basically expands to

```
let res = match u - v {
Left(s) => s,
Right(s) => s,
};
```

Which is trying to assign both an `f32`

and a `Vec2`

to `res`

.

Maybe you meant to:

```
let res = u - v;
for_both!(res, s => println!("u - v: {s:#?}"));
```

But `Either`

implements `Debug`

when both it's generic types do, so you can just

```
let res = u - v;
println!("u - v: {res:#?}");
```

(Both require deriving `Debug`

for your `Vec2`

.)

Playground. (I ignored other preexiting warnings).

1 Like

Wow, I didn't even consider that match statements have to give the same type. Not gonna lie, it's pretty hard to choose which answer is better, however, I think yours is just a tad more insightful. Thank you.