diff --git a/src/lib.rs b/src/lib.rs index bfd0819e9..1dbae3bcf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -269,7 +269,7 @@ html_root_url = "https://docs.rs/log/0.4.14" )] #![warn(missing_docs)] -#![deny(missing_debug_implementations)] +#![deny(missing_debug_implementations, unconditional_recursion)] #![cfg_attr(all(not(feature = "std"), not(test)), no_std)] // When compiled for the rustc compiler itself we want to make sure that this is // an unstable crate @@ -1250,6 +1250,22 @@ impl Log for NopLogger { fn flush(&self) {} } +impl Log for &'_ T +where + T: ?Sized + Log, +{ + fn enabled(&self, metadata: &Metadata) -> bool { + (**self).enabled(metadata) + } + + fn log(&self, record: &Record) { + (**self).log(record) + } + fn flush(&self) { + (**self).flush() + } +} + #[cfg(feature = "std")] impl Log for std::boxed::Box where @@ -1267,6 +1283,23 @@ where } } +#[cfg(feature = "std")] +impl Log for std::sync::Arc +where + T: ?Sized + Log, +{ + fn enabled(&self, metadata: &Metadata) -> bool { + self.as_ref().enabled(metadata) + } + + fn log(&self, record: &Record) { + self.as_ref().log(record) + } + fn flush(&self) { + self.as_ref().flush() + } +} + /// Sets the global maximum log level. /// /// Generally, this should only be called by the active logging implementation. @@ -1842,4 +1875,35 @@ mod tests { .expect("invalid value") ); } + + // Test that the `impl Log for Foo` blocks work + // This test mostly operates on a type level, so failures will be compile errors + #[test] + fn test_foreign_impl() { + use super::Log; + #[cfg(feature = "std")] + use std::sync::Arc; + + fn assert_is_log() {} + + assert_is_log::<&dyn Log>(); + + #[cfg(feature = "std")] + assert_is_log::>(); + + #[cfg(feature = "std")] + assert_is_log::>(); + + // Assert these statements for all T: Log + ?Sized + #[allow(unused)] + fn forall() { + #[cfg(feature = "std")] + assert_is_log::>(); + + assert_is_log::<&T>(); + + #[cfg(feature = "std")] + assert_is_log::>(); + } + } }