Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1250,6 +1250,22 @@ impl Log for NopLogger {
fn flush(&self) {}
}

impl<T> 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<T> Log for std::boxed::Box<T>
where
Expand All @@ -1267,6 +1283,23 @@ where
}
}

#[cfg(feature = "std")]
impl<T> Log for std::sync::Arc<T>
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.
Expand Down Expand Up @@ -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<T: Log + ?Sized>() {}

assert_is_log::<&dyn Log>();

#[cfg(feature = "std")]
assert_is_log::<Box<dyn Log>>();

#[cfg(feature = "std")]
assert_is_log::<Arc<dyn Log>>();

// Assert these statements for all T: Log + ?Sized
#[allow(unused)]
fn forall<T: Log + ?Sized>() {
#[cfg(feature = "std")]
assert_is_log::<Box<T>>();

assert_is_log::<&T>();

#[cfg(feature = "std")]
assert_is_log::<Arc<T>>();
}
}
}