Skip to content

Commit

Permalink
Merge pull request #53 from dtolnay/supertrait
Browse files Browse the repository at this point in the history
Detect missing supertrait on serialize_trait_object calls
  • Loading branch information
dtolnay authored Mar 15, 2022
2 parents 76854cb + 8962299 commit b92d2e4
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 3 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ rust-version = "1.31"
serde = { version = "1.0.63", default-features = false }

[dev-dependencies]
rustversion = "1.0"
serde_cbor = "0.11"
serde_derive = "1.0"
serde_json = "1.0"
trybuild = { version = "1.0.49", features = ["diff"] }

[features]
# Note: at least one of "std" or "alloc" must be enabled.
Expand Down
13 changes: 11 additions & 2 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,22 @@ macro_rules! __internal_serialize_trait_object {

// Expand into four impls.
(sendsync ($($generics:tt)*) ($($path:tt)*) ($($bound:tt)*)) => {
$crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)*) ($($bound)*));
$crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)*) ($($bound)*) {
fn __check_erased_serialize_supertrait<__T, $($generics)*>()
where
__T: ?$crate::private::Sized + $($path)*,
$($bound)*
{
$crate::private::require_erased_serialize_impl::<__T>();
}
});
$crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)* + $crate::private::Send) ($($bound)*));
$crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)* + $crate::private::Sync) ($($bound)*));
$crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)* + $crate::private::Send + $crate::private::Sync) ($($bound)*));
};

// The impl.
(impl ($($generics:tt)*) ($($path:tt)*) ($($bound:tt)*)) => {
(impl ($($generics:tt)*) ($($path:tt)*) ($($bound:tt)*) $({$($body:tt)*})*) => {
impl<'erased, $($generics)*> $crate::private::serde::Serialize for dyn $($path)* + 'erased
where
$($bound)*
Expand All @@ -95,6 +103,7 @@ macro_rules! __internal_serialize_trait_object {
where
S: $crate::private::serde::Serializer,
{
$($($body)*)*
$crate::serialize(self, serializer)
}
}
Expand Down
8 changes: 7 additions & 1 deletion src/private.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
//! Not public API. Used as `$crate::private` by macros.
pub use core::marker::{Send, Sync};
pub use core::marker::{Send, Sized, Sync};
pub use core::result::Result;
pub use serde;

pub fn require_erased_serialize_impl<T>()
where
T: ?Sized + crate::Serialize,
{
}
7 changes: 7 additions & 0 deletions tests/compiletest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#[rustversion::attr(not(nightly), ignore)]
#[cfg_attr(miri, ignore)]
#[test]
fn ui() {
let t = trybuild::TestCases::new();
t.compile_fail("tests/ui/*.rs");
}
7 changes: 7 additions & 0 deletions tests/ui/missing-supertrait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use erased_serde::serialize_trait_object;

pub trait MyTrait {}

serialize_trait_object!(MyTrait);

fn main() {}
17 changes: 17 additions & 0 deletions tests/ui/missing-supertrait.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0277]: the trait bound `__T: erased_serde::private::serde::Serialize` is not satisfied
--> tests/ui/missing-supertrait.rs:5:1
|
5 | serialize_trait_object!(MyTrait);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `erased_serde::private::serde::Serialize` is not implemented for `__T`
|
= note: required because of the requirements on the impl of `erased_serde::Serialize` for `__T`
note: required by a bound in `require_erased_serialize_impl`
--> src/private.rs
|
| T: ?Sized + crate::Serialize,
| ^^^^^^^^^^^^^^^^ required by this bound in `require_erased_serialize_impl`
= note: this error originates in the macro `$crate::__internal_serialize_trait_object` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting this bound
|
85| __T + erased_serde::private::serde::Serialize: ?$crate::private::Sized + $($path)*,
| +++++++++++++++++++++++++++++++++++++++++

0 comments on commit b92d2e4

Please sign in to comment.