Why?
When you make a tuple
(p.choice, p.age)
you memcpy both p.choice and p.age from your Person .
This is normal for p.age because it is of type Copy - you can continue to use the old value after memcpy ing from it.
p.choices is of type Choices , which is not Copy . This means that memcpy treated as a "move", so the old value is not used. This means that p is in an invalid state, so you cannot invoke announce on it.
Solution No. 1
Since Choices is a trivial enum , you can simply #[derive(Copy, Clone)] . This means that you are allowed to continue using the old p.choices .
If you can safely make Choices Clone , then you will have to Clone it in match .
Decision No. 2
You can take p.choices from the link:
match (&p.choice, p.age) { (&Choices::Good, a) if a < 80 => { announce(p); } ... }
This only works because &Choices::Good is an exact match, so borrowing may be refused. If you used
match (&p.choice, p.age) { (&x, a) if a < 80 => { announce(p); } ... }
the lesson will still be active, and therefore the transition when calling announce(p) will end with an error - moving will invalidate the active borrowed variable.
Notes
You are moving a lot here - submitting multiple links is much more flexible! There is no reason for announce consume Person - he just needs to take a look at it. Accepting when you can take a link is only recommended for small types of Copy .
Note that if announce take the link means that match can also be held on links inside p , which makes it more widely applicable.
to_string is mainly used for non-string objects. into and to_owned faster, and into also much shorter.
struct Person { name: String, age: i32, choice: Choices } #[derive(Copy, Clone, Debug)] enum Choices { Good, Neutral, Evil } fn find(p: &Person) { match (p.choice, p.age) { (Choices::Good, a) if a < 80 => { announce(p); } (_, a) if a >= 80 => { println!("You're too old to care."); } _ => { println!("You're not very nice!") } } } fn announce(p: &Person) { println!("Your name is {}. You are {:?}.", p.name, p.choice); } fn main() { let p = Person { name: "Bob".into(), age: 20, choice: Choices::Good }; find(&p); }