1

I'm trying to cast a struct which implements a trait to a trait object of that same trait. The problem is that the trait object needs to wrapped in an Arc and I can't implement the Into trait for an Arc. Due to the following code not compiling:

use std::sync::Arc;

trait Foo { }

struct Bar {}

impl Foo for Bar { }

impl Into<Arc<dyn Foo>> for Arc<Bar> {
    fn into(self) -> Arc<dyn Foo> { self }
}

fn bar_to_foo(bar: Arc<Bar>) -> Arc<dyn Foo> {
    bar.into()
}

This fails with the following compiler message:

error[E0119]: conflicting implementations of trait `std::convert::Into<std::sync::Arc<(dyn Foo + 'static)>>` for type `std::sync::Arc<Bar>`:
 --> src/lib.rs:9:1
  |
9 | impl Into<Arc<dyn Foo>> for Arc<Bar> {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: conflicting implementation in crate `core`:
          - impl<T, U> std::convert::Into<U> for T
            where U: std::convert::From<T>;
  = note: upstream crates may add a new impl of trait `std::convert::From<std::sync::Arc<Bar>>` for type `std::sync::Arc<(dyn Foo + 'static)>` in future versions

error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
 --> src/lib.rs:9:1
  |
9 | impl Into<Arc<dyn Foo>> for Arc<Bar> {
  | ^^^^^------------------^^^^^--------
  | |    |                      |
  | |    |                      `std::sync::Arc` is not defined in the current crate
  | |    `std::sync::Arc` is not defined in the current crate
  | impl doesn't use only types from inside the current crate
  |
  = note: define and implement a trait or new type instead

error: aborting due to 2 previous errors

However I cannot do the following either:

use std::sync::Arc;

trait Foo { }

struct Bar {}

impl Foo for Bar { }

impl Into<dyn Foo> for Bar {
    fn into(self) -> dyn Foo { self }
}

fn bar_to_foo(bar: Arc<Bar>) -> Arc<dyn Foo> {
    bar.into()
}

Because that results in:

error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time
 --> src/lib.rs:9:6
  |
9 | impl Into<dyn Foo> for Bar {
  |      ^^^^^^^^^^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `(dyn Foo + 'static)`

I'm probably missing something obvious, but any help would be greatly appreciated!

user1870238
  • 447
  • 7
  • 20

1 Answers1

1

I'm a moron:

use std::sync::Arc;

trait Foo { }

struct Bar {}

impl Foo for Bar { }

fn bar_to_foo(bar: Arc<Bar>) -> Arc<dyn Foo> {
    bar
}

I'll show myself out.

user1870238
  • 447
  • 7
  • 20
  • This does not work if I want to accept `Option>` and return `Option>`. Any clue on how to handle this scenario? – Meet Sinojia Nov 17 '20 at 12:45
  • Also, this doesn't work when the implementor is itself a `dyn`: https://stackoverflow.com/questions/66067777/how-to-upcast-an-rcdyn-foo – dspyz Feb 05 '21 at 17:27