Move out of a shared reference

Hello all,

I'm having a move out of shared reference error when I try to return a trait object from an enum.
Let me show you:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=db00b633f3dc1671b8611d6ea636af99

trait Trait {}
impl Trait for String {}

enum E {
    Int(i32),
    Obj(Box<dyn Trait>)
}

impl E {
    fn to_trait(&self) -> Box<dyn Trait> {
        match self {
            Self::Int(i) => Box::new(i.to_string()) as Box<dyn Trait>,
            Self::Obj(o) => *o,
//                          ^^ move occurs because `*o` has type `std::boxed::Box<dyn Trait>`, which does not implement the `Copy` trait

        }
    }
}

If I try to change the to_trait signature to return a reference &Box<dyn Trait>, I get another error because I try to return a temporary object in the case of Int:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=50b713d696af4f7b527cd0e971907062

impl E {
    fn to_trait(&self) -> &Box<dyn Trait> {
        match self {
            Self::Int(i) => &(Box::new(i.to_string()) as Box<dyn Trait>),
//                           ------------------------------------------- temporary value created here

            Self::Obj(o) => o,
        }
//      ^ returns a value referencing data owned by the current function
    }
}

Is there a solution to my problem ?

The issue is that in one case, you're returning a borrow, and in the other, you're returning an owned value. You should probably go for an enum with two cases instead. See Cow for something similar, though I'm not sure if it applies here directly.

Hi, thanks. What do you mean by that?

Take a look at this example: playground

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.