From 71faefd21ebfbe457ec2c93bec57cd7068f7b1d4 Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Tue, 11 Jun 2024 22:15:09 -0700 Subject: [PATCH] Reduce usages of unsafe --- crates/nu-path/src/path.rs | 58 +++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/crates/nu-path/src/path.rs b/crates/nu-path/src/path.rs index 41aaefd45e..6de1dd9587 100644 --- a/crates/nu-path/src/path.rs +++ b/crates/nu-path/src/path.rs @@ -557,10 +557,7 @@ impl fmt::Debug for Path
{ impl Clone for Box> { #[inline] fn clone(&self) -> Self { - // Safety: `Path` is a repr(transparent) wrapper around `std::path::Path`. - let path: Box = self.inner.into(); - let ptr = Box::into_raw(path) as *mut Path; - unsafe { Box::from_raw(ptr) } + std_box_to_box(self.inner.into()) } } @@ -1016,6 +1013,13 @@ impl<'a, Form: PathForm> IntoIterator for &'a PathBuf { } } +#[inline] +fn box_to_box_unchecked(path: Box>) -> Box> { + // Safety: `Path` and `Path` differ only by PhantomData tag. + let ptr = Box::into_raw(path) as *mut Path; + unsafe { Box::from_raw(ptr) } +} + #[inline] fn std_box_to_box(path: Box) -> Box> { // Safety: `Path` is a repr(transparent) wrapper around `std::path::Path`. @@ -1023,6 +1027,20 @@ fn std_box_to_box(path: Box) -> Box> unsafe { Box::from_raw(ptr) } } +#[inline] +fn std_arc_to_arc(path: Arc) -> Arc> { + // Safety: `Path` is a repr(transparent) wrapper around `std::path::Path`. + let ptr = Arc::into_raw(path) as *mut Path; + unsafe { Arc::from_raw(ptr) } +} + +#[inline] +fn std_rc_to_rc(path: Rc) -> Rc> { + // Safety: `Path` is a repr(transparent) wrapper around `std::path::Path`. + let ptr = Rc::into_raw(path) as *mut Path; + unsafe { Rc::from_raw(ptr) } +} + /* ================================================================================ AsRef @@ -1166,9 +1184,7 @@ impl_from!([CanonicalPathBuf] => AbsolutePathBuf |buf| { buf.cast_into() }); #[inline] fn box_to_box, To: PathForm>(path: Box>) -> Box> { - // Safety: `Path` and `Path` differ only by PhantomData tag. - let ptr = Box::into_raw(path) as *mut Path; - unsafe { Box::from_raw(ptr) } + box_to_box_unchecked(path) } impl_from!([Box, Box, Box] => Box |path| { box_to_box(path) } @@ -1220,10 +1236,7 @@ impl_from!([Cow<'_, CanonicalPath>] => Box |cow| { cow_to_box(cow) #[inline] fn buf_to_arc, To: PathForm>(buf: PathBuf) -> Arc> { - // Safety: `Path` is a repr(transparent) wrapper around `std::path::Path`. - let arc: Arc = buf.inner.into(); - let ptr = Arc::into_raw(arc) as *const Path; - unsafe { Arc::from_raw(ptr) } + std_arc_to_arc(buf.inner.into()) } impl_from!( PathBuf => Arc> |buf| { buf_to_arc(buf) }); impl_from!([RelativePathBuf, AbsolutePathBuf, CanonicalPathBuf] => Arc @@ -1233,10 +1246,7 @@ impl_from!([CanonicalPathBuf] => Arc |buf| { buf_to_arc(buf) }); #[inline] fn buf_to_rc, To: PathForm>(buf: PathBuf) -> Rc> { - // Safety: `Path` is a repr(transparent) wrapper around `std::path::Path`. - let rc: Rc = buf.inner.into(); - let ptr = Rc::into_raw(rc) as *const Path; - unsafe { Rc::from_raw(ptr) } + std_rc_to_rc(buf.inner.into()) } impl_from!( PathBuf => Rc> |buf| { buf_to_rc(buf) }); impl_from!([RelativePathBuf, AbsolutePathBuf, CanonicalPathBuf] => Rc @@ -1304,20 +1314,14 @@ impl<'a, Source: PathCast, To: PathForm> From<&'a PathBuf> for Cow<' impl, To: PathForm> From<&Path> for Arc> { #[inline] fn from(path: &Path) -> Self { - // Safety: `Path` is a repr(transparent) wrapper around `std::path::Path`. - let arc: Arc = path.inner.into(); - let ptr = Arc::into_raw(arc) as *const Path; - unsafe { Arc::from_raw(ptr) } + std_arc_to_arc(path.inner.into()) } } impl, To: PathForm> From<&Path> for Rc> { #[inline] fn from(path: &Path) -> Self { - // Safety: `Path` is a repr(transparent) wrapper around `std::path::Path`. - let rc: Rc = path.inner.into(); - let ptr = Rc::into_raw(rc) as *const Path; - unsafe { Rc::from_raw(ptr) } + std_rc_to_rc(path.inner.into()) } } @@ -1595,9 +1599,7 @@ impl TryFrom> for Box { #[inline] fn try_from(path: Box) -> Result { if path.is_relative() { - // Safety: `Path` and `RelativePath` differ only by PhantomData tag. - let ptr = Box::into_raw(path) as *mut RelativePath; - Ok(unsafe { Box::from_raw(ptr) }) + Ok(box_to_box_unchecked(path)) } else { Err(path) } @@ -1610,9 +1612,7 @@ impl TryFrom> for Box { #[inline] fn try_from(path: Box) -> Result { if path.is_absolute() { - // Safety: `Path` and `AbsolutePath` differ only by PhantomData tag. - let ptr = Box::into_raw(path) as *mut AbsolutePath; - Ok(unsafe { Box::from_raw(ptr) }) + Ok(box_to_box_unchecked(path)) } else { Err(path) }