diff --git a/impl_cast/src/lib.rs b/impl_cast/src/lib.rs index 38e75ad..ccf3269 100644 --- a/impl_cast/src/lib.rs +++ b/impl_cast/src/lib.rs @@ -90,39 +90,42 @@ pub fn device(attr: TokenStream, item: TokenStream) -> TokenStream { .iter() .map(|device_trait| { quote! { + // Default impl impl #name for T - where - T: #interface_ident + #device_trait + 'static, - { - fn consume(self: Box) -> Option> { - Some(self) - } - - fn cast(&self) -> Option<&(dyn #device_trait + 'static)> { - Some(self) - } - - fn cast_mut(&mut self) -> Option<&mut (dyn #device_trait + 'static)> { - Some(self) - } + where + T: #interface_ident + 'static, + { + default fn consume(self: Box) -> Option> { + None } - impl #name for T - where - T: #interface_ident + ?Sized, - { - default fn consume(self: Box) -> Option> { - None - } - - default fn cast(&self) -> Option<&(dyn #device_trait + 'static)> { - None - } - - default fn cast_mut(&mut self) -> Option<&mut (dyn #device_trait + 'static)> { - None - } + default fn cast(&self) -> Option<&(dyn #device_trait + 'static)> { + None } + + default fn cast_mut(&mut self) -> Option<&mut (dyn #device_trait + 'static)> { + None + } + } + + // Specialization, should not cause any unsoundness as we dispatch based on + // #device_trait + impl #name for T + where + T: #interface_ident + #device_trait + 'static, + { + fn consume(self: Box) -> Option> { + Some(self) + } + + fn cast(&self) -> Option<&(dyn #device_trait + 'static)> { + Some(self) + } + + fn cast_mut(&mut self) -> Option<&mut (dyn #device_trait + 'static)> { + Some(self) + } + } } }) .fold(quote! {}, |acc, x| { @@ -149,7 +152,7 @@ pub fn device_trait(_attr: TokenStream, item: TokenStream) -> TokenStream { let mut interface: ItemTrait = parse_macro_input!(item); interface.supertraits.push(TypeParamBound::Verbatim(quote! { - ::core::marker::Sync + ::core::marker::Send + 'static + ::core::marker::Sync + ::core::marker::Send })); #[cfg(feature = "debug")]