diff --git a/src/display.rs b/src/display.rs index 2b0ba5a..58d11e4 100644 --- a/src/display.rs +++ b/src/display.rs @@ -1,55 +1,38 @@ -use std::fmt::{self, Display}; -use std::path::{Path, PathBuf}; +use std::fmt::Display; +use std::path::{self, Path, PathBuf}; #[doc(hidden)] -pub trait AsDisplay { - type Target: Display + ?Sized; +pub trait AsDisplay<'a> { + type Target: Display; - fn as_display(&self) -> &Self::Target; + fn as_display(&'a self) -> Self::Target; } -impl AsDisplay for &T { - type Target = T; +impl<'a, T> AsDisplay<'a> for &T +where + T: Display + 'a, +{ + type Target = &'a T; - fn as_display(&self) -> &Self::Target { - self + fn as_display(&'a self) -> Self::Target { + *self } } -impl AsDisplay for Path { - type Target = PathDisplay; +impl<'a> AsDisplay<'a> for Path { + type Target = path::Display<'a>; #[inline] - fn as_display(&self) -> &Self::Target { - PathDisplay::new(self) + fn as_display(&'a self) -> Self::Target { + self.display() } } -impl AsDisplay for PathBuf { - type Target = PathDisplay; +impl<'a> AsDisplay<'a> for PathBuf { + type Target = path::Display<'a>; #[inline] - fn as_display(&self) -> &Self::Target { - PathDisplay::new(self.as_path()) - } -} - -#[doc(hidden)] -#[repr(transparent)] -pub struct PathDisplay(Path); - -impl PathDisplay { - #[inline] - fn new(path: &Path) -> &Self { - // SAFETY: PathDisplay is repr(transparent) so casting pointers between - // it and its payload is safe. - unsafe { &*(path as *const Path as *const Self) } - } -} - -impl Display for PathDisplay { - #[inline] - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - self.0.display().fmt(formatter) + fn as_display(&'a self) -> Self::Target { + self.display() } } diff --git a/tests/ui/no-display.stderr b/tests/ui/no-display.stderr index 26dc842..0f47c24 100644 --- a/tests/ui/no-display.stderr +++ b/tests/ui/no-display.stderr @@ -9,7 +9,7 @@ error[E0599]: the method `as_display` exists for reference `&NoDisplay`, but its | = note: the following trait bounds were not satisfied: `NoDisplay: std::fmt::Display` - which is required by `&NoDisplay: AsDisplay` + which is required by `&NoDisplay: AsDisplay<'_>` note: the trait `std::fmt::Display` must be implemented --> $RUST/core/src/fmt/mod.rs |