Is this possible without copy/clone and if not what are my alternatives?

So I'm likely to be disappointed here but I was trying to be able to hold onto a value and pass it without Clone and/or Copy as this is a type in an upstream crate.

/////////////// Begin Someone Else's crate ///////////////////////////
mod krate {

    #[derive(Debug)]
    pub struct Sentence {
        word: String,
        len: usize,
    }

    #[derive(Debug)]
    pub struct Paragraph {
        pub sentence: Sentence,
    }

    impl Paragraph {
        pub fn new() -> Self {
            Self {
                sentence: Sentence {
                    word: String::from("To be or not to be?"),
                    len: 19,
                },
            }
        }
    }
}

/////////////// End Someone Else's crate   ///////////////////////////


// There are other non-problem types here but
// for MCVE the problem type will suffice
#[derive(Debug)]
struct Private {
    upstream: krate::Sentence,
}

#[derive(Debug)]
struct LocalSentence(pub krate::Paragraph, Private);

impl LocalSentence {
    fn _set_upstream(&mut self, upstream: krate::Sentence) {
        self.1.upstream = upstream;
    }
}

fn main() {
    let to_be = krate::Paragraph::new();
    let private = Private{upstream: to_be.sentence};
    let encapsulated = LocalSentence(to_be, private);
    println!("{encapsulated:?}");
}

Here's a Rust Explorer to toy with if you wish.

This obviously fails to compile with:

error[E0382]: use of partially moved value: `to_be`
  --> src/main.rs:54:38
   |
53 |     let private = Private{upstream: to_be.sentence};
   |                                     -------------- value partially moved here
54 |     let encapsulated = LocalSentence(to_be, private);
   |                                      ^^^^^ value used here after partial move
   |
   = note: partial move occurs because `to_be.sentence` has type `Sentence`, which does not implement the `Copy` trait

For more information about this error, try `rustc --explain E0382`.

I've tried OnceCell<krate::Sentence>, OnceLock<krate::Sentence>, and realized that I'm likely misunderstanding something here. I don't mind unsafe but I that's not where I think I should have to go either.

What is your goal with this? You can't have multiple owners for a given value, because it doesn't make sense.

If you need reference counting, use Rc.

Why aren't you using references? Are the upstream values supposed to be changed while you're holding the references?


// There are other non-problem types here but
// for MCVE the problem type will suffice
#[derive(Debug)]
struct Private<'up> {
    upstream: &'up krate::Sentence,
}

#[derive(Debug)]
struct LocalSentence<'up>(pub &'up krate::Paragraph, Private<'up>);

// impl LocalSentence {
//     fn _set_upstream(&mut self, upstream: &krate::Sentence) {
//         self.1.upstream = upstream;
//     }
// }

fn main() {
    let to_be = krate::Paragraph::new();
    let private = Private{upstream: &to_be.sentence};
    let encapsulated = LocalSentence(&to_be, private);
    println!("{encapsulated:?}");
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.