diff options
author | Martin Fischer <martin@push-f.com> | 2021-11-20 18:53:55 +0100 |
---|---|---|
committer | Martin Fischer <martin@push-f.com> | 2021-11-20 19:19:29 +0100 |
commit | 9044eb941a310e4120dab93a43e6630efef72e4a (patch) | |
tree | 40940640b1ace6a11a6b89ea04a0d70b1f67e38a | |
parent | 3170127a4ef79c43018775934c7e0444dc828b2d (diff) |
assert that dynamized traits are object-safe
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | src/lib.rs | 10 | ||||
-rw-r--r-- | tests/doctests.md | 19 |
3 files changed, 30 insertions, 1 deletions
@@ -20,7 +20,7 @@ let object = &client as &dyn Client; The last line of the above code fails to compile with: -> error[E0191]: the value of the associated type `Error` (from trait `Client`) +> error\[E0191\]: the value of the associated type `Error` (from trait `Client`) > must be specified Sometimes you however want a trait object to be able to encompass trait @@ -308,12 +308,18 @@ pub fn dynamize(_attr: TokenStream, input: TokenStream) -> TokenStream { let blanket_impl = generate_blanket_impl(&dyn_trait, &original_trait, &method_impls); + let dyn_trait_name = &dyn_trait.ident; + let (impl_generics, ty_generics, where_clause) = dyn_trait.generics.split_for_impl(); + let expanded = quote! { #original_trait #(#dyn_trait_attrs)* #dyn_trait + // assert that dyn_trait can actually be made into an object + impl #impl_generics dyn #dyn_trait_name #ty_generics #where_clause {} + #(#blanket_impl_attrs)* #blanket_impl }; @@ -432,3 +438,7 @@ fn path_segment_for_trait(sometrait: &ItemTrait) -> PathSegment { }, } } + +#[doc = include_str!("../tests/doctests.md")] +#[cfg(doctest)] +struct Doctests; diff --git a/tests/doctests.md b/tests/doctests.md new file mode 100644 index 0000000..ef557fe --- /dev/null +++ b/tests/doctests.md @@ -0,0 +1,19 @@ +Tests that the object-safety assertion via `impl dyn` is working: + +```rust compile_fail +trait ObjectUnsafe: Sized {} + +#[dynamize::dynamize] +trait Trait: ObjectUnsafe {} +``` + +```rust compile_fail +trait ObjectUnsafe: Sized {} + +#[dynamize::dynamize] +trait Trait { + type A: ObjectUnsafe; + + fn f(&self) -> Self::A; +} +``` |