Tenho uma situação na minha base de código em que uma função possui um objeto de característica em caixa chamando uma função que espera um implementador dessa característica, e recebi a mensagem de erro mostrada abaixo. Por algum motivo, a Box não implementa Trait por padrão.
use std::any::Any;
trait SubTrait: DynClone {}
trait DynClone: Any {
fn dyn_clone(&self) -> Box<dyn DynClone>;
}
impl<T: Any + Clone + 'static> DynClone for T {
fn dyn_clone(&self) -> Box<dyn DynClone> {
Box::new(Clone::clone(self))
}
}
fn test_outer() {
test::<Box<dyn SubTrait>>();
}
fn test<L: SubTrait>() {}
error[E0277]: the trait bound `Box<(dyn SubTrait + 'static)>: SubTrait` is not satisfied
--> src\ecs\schedule.rs:124:9
|
124 | test::<Box<dyn SubTrait>>();
| ^^^^^^^^^^^^^^^^^ the trait `SubTrait` is not implemented for `Box<(dyn SubTrait + 'static)>`
|
Não entendo completamente por que isso acontece, mas estou mais perplexo com uma correção que funcionou
impl DynClone for Box<dyn SubTrait> {
fn dyn_clone(&self) -> Box<dyn DynClone> {
(self as &dyn DynClone).dyn_clone()
}
}
impl SubTrait for Box<dyn SubTrait> {}
Tentei fazer isso esperando que fosse rejeitado devido a uma implementação conflitante, mas foi aceito por algum motivo.
Por que essas implementações não são conflitantes?
impl DynClone for Box<dyn SubTrait> {
fn dyn_clone(&self) -> Box<dyn DynClone> {
(self as &dyn DynClone).dyn_clone()
}
}
impl<T: Any + Clone + 'static> DynClone for T {
fn dyn_clone(&self) -> Box<dyn DynClone> {
Box::new(Clone::clone(self))
}
}
Eu sei que não é por causa dos limites de características em T, porque Rust não considera limites de características ou cláusulas where ao verificar conflitos.
Eu até verifiquei que os limites de características em T não são a correção com outro tipo que não é clone, o que leva a essa mensagem de erro.
use std::sync::mpsc::Receiver;
impl DynClone for Receiver<()> {
fn dyn_clone(&self) -> Box<dyn DynClone> {
Box::new(25_i32)
}
}
error[E0119]: conflicting implementations of trait `schedule::test::DynClone` for type `std::sync::mpsc::Receiver<()>`
--> src\ecs\schedule.rs:138:1
|
117 | impl<T: Any + Clone + 'static> DynClone for T {
| --------------------------------------------- first implementation here
...
138 | impl DynClone for Receiver<()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::sync::mpsc::Receiver<()>`
|
= note: upstream crates may add a new impl of trait `std::clone::Clone` for type `std::sync::mpsc::Receiver<()>` in future versions
Alguém pode explicar o que está acontecendo aqui?