Dry answer: In practice, you try to not mutate values you receive unless you know you own them. Usually it's clear from the type signature. If ints are sent over the channel, or structs each containing an int and string, you know you can do whatever you want with them. If it's ambiguous, the sender should document whether the receiver has ownership.
I think with 1 sender and 1 receiver the common solution in Rust is the same, to copy (or maybe move) the values sent... the type system provides some safety guarantees but I doubt it would be much different for performance. You wouldn't be able to send an immutable reference over a channel in Rust, since the compiler wouldn't know where the reference's lifetime ends. You could resort to refcounting, but you would probably only put in the effort if the data structure was large enough that copying was prohibitively expensive.
I think with 1 sender and 1 receiver the common solution in Rust is the same, to copy (or maybe move) the values sent... the type system provides some safety guarantees but I doubt it would be much different for performance. You wouldn't be able to send an immutable reference over a channel in Rust, since the compiler wouldn't know where the reference's lifetime ends. You could resort to refcounting, but you would probably only put in the effort if the data structure was large enough that copying was prohibitively expensive.