From bd640d10e638d82458f9e79b80e68147eeb12bf9 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 2 Sep 2023 12:51:52 -0700 Subject: [PATCH 1/2] Remove unsafe code from AsDisplay --- src/display.rs | 47 ++++++++++++++++---------------------- tests/ui/no-display.stderr | 2 +- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/display.rs b/src/display.rs index 2b0ba5a..e765c18 100644 --- a/src/display.rs +++ b/src/display.rs @@ -2,52 +2,45 @@ use std::fmt::{self, Display}; use std::path::{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 = PathDisplay<'a>; #[inline] - fn as_display(&self) -> &Self::Target { - PathDisplay::new(self) + fn as_display(&'a self) -> Self::Target { + PathDisplay(self) } } -impl AsDisplay for PathBuf { - type Target = PathDisplay; +impl<'a> AsDisplay<'a> for PathBuf { + type Target = PathDisplay<'a>; #[inline] - fn as_display(&self) -> &Self::Target { - PathDisplay::new(self.as_path()) + fn as_display(&'a self) -> Self::Target { + PathDisplay(self.as_path()) } } #[doc(hidden)] -#[repr(transparent)] -pub struct PathDisplay(Path); +pub struct PathDisplay<'a>(&'a 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 { +impl<'a> Display for PathDisplay<'a> { #[inline] fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { self.0.display().fmt(formatter) 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 | From bb49bb3fa80fc12250c19a75ac5c5cf6e44c2603 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 2 Sep 2023 13:01:50 -0700 Subject: [PATCH 2/2] Delete PathDisplay type --- src/display.rs | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/display.rs b/src/display.rs index e765c18..58d11e4 100644 --- a/src/display.rs +++ b/src/display.rs @@ -1,5 +1,5 @@ -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<'a> { @@ -20,29 +20,19 @@ where } impl<'a> AsDisplay<'a> for Path { - type Target = PathDisplay<'a>; + type Target = path::Display<'a>; #[inline] fn as_display(&'a self) -> Self::Target { - PathDisplay(self) + self.display() } } impl<'a> AsDisplay<'a> for PathBuf { - type Target = PathDisplay<'a>; + type Target = path::Display<'a>; #[inline] fn as_display(&'a self) -> Self::Target { - PathDisplay(self.as_path()) - } -} - -#[doc(hidden)] -pub struct PathDisplay<'a>(&'a Path); - -impl<'a> Display for PathDisplay<'a> { - #[inline] - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - self.0.display().fmt(formatter) + self.display() } }