1
votes

I came across this issue while experimenting with different ways to solve this question.

I'm trying to define a trait which takes an argument by reference, and returns Self, like this:

struct X {}

trait CopyFrom {
    fn copy_from(&x: X) -> Self;
}

The error I get is:

error[E0642]: patterns aren't allowed in functions without bodies
 --> src/main.rs:5:18
  |
5 |     fn copy_from(&x: X) -> Self;
  |                  ^^ pattern not allowed in function without body

If I take x by value it compiles fine (but that would consume the argument, which I don't want).

The Rust reference has this to say:

The kinds of patterns for parameters is limited to one of the following:

  • IDENTIFIER
  • mut IDENTIFIER
  • _
  • & IDENTIFIER
  • && IDENTIFIER

Beginning in the 2018 edition, function or method parameter patterns are no longer optional. Also, all irrefutable patterns are allowed as long as there is a body. Without a body, the limitations listed above are still in effect.

I was not able to find anything else that would explain why I can't define a trait function that takes an argument by reference.

1

1 Answers

1
votes

You're using the wrong syntax here — &x: X is a reference pattern that dereferences the argument of type X; in other words,

fn f(&x: X) {
    // ...
}

is equivalent to

fn f(x: X) {
    let &x = x;
}

which, in turn, means

fn f(x: X) {
    let x = *x;
}

Instead, you want to make the parameter itself a reference:

fn f(x: &X) { // take argument by reference
    // ...
}