match_list: remove unsafe std::mem::transmute

By adding a lifetime to the `MatchList` trait, we don't need
to use unsafe code to transmute self anymore.

Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
This commit is contained in:
Gabriel Goller 2023-09-18 15:41:08 +02:00 committed by Wolfgang Bumiller
parent d7e1d50bfa
commit 762d1e9bc3

View File

@ -412,41 +412,42 @@ impl MatchListEntry for &'_ &'_ MatchEntry {
/// [`VecDeque`](std::collections::VecDeque) etc. /// [`VecDeque`](std::collections::VecDeque) etc.
/// ///
/// This makes it easier to use slices over entries or references to entries. /// This makes it easier to use slices over entries or references to entries.
pub trait MatchList { pub trait MatchList<'a> {
/// Check whether this list contains anything matching a prefix of the specified path, and the /// Check whether this list contains anything matching a prefix of the specified path, and the
/// specified file mode. Gets the file_mode lazily, only if needed. /// specified file mode. Gets the file_mode lazily, only if needed.
fn matches<P, U>(&self, path: P, get_file_mode: U) -> Result<Option<MatchType>, U::Error> fn matches<P, U>(&'a self, path: P, get_file_mode: U) -> Result<Option<MatchType>, U::Error>
where where
P: AsRef<[u8]>, P: AsRef<[u8]>,
U: GetFileMode; U: GetFileMode;
/// Check whether this list contains anything exactly matching the path and mode. Gets the /// Check whether this list contains anything exactly matching the path and mode. Gets the
/// file_mode lazily, only if needed. /// file_mode lazily, only if needed.
fn matches_exact<P, U>(&self, path: P, get_file_mode: U) -> Result<Option<MatchType>, U::Error> fn matches_exact<P, U>(
&'a self,
path: P,
get_file_mode: U,
) -> Result<Option<MatchType>, U::Error>
where where
P: AsRef<[u8]>, P: AsRef<[u8]>,
U: GetFileMode; U: GetFileMode;
} }
impl<'a, T> MatchList for T impl<'a, T> MatchList<'a> for T
where where
T: 'a + ?Sized, T: 'a + ?Sized,
&'a T: IntoIterator, &'a T: IntoIterator,
<&'a T as IntoIterator>::IntoIter: DoubleEndedIterator, <&'a T as IntoIterator>::IntoIter: DoubleEndedIterator,
<&'a T as IntoIterator>::Item: MatchListEntry, <&'a T as IntoIterator>::Item: MatchListEntry,
{ {
fn matches<P, G>(&self, path: P, get_file_mode: G) -> Result<Option<MatchType>, G::Error> fn matches<P, G>(&'a self, path: P, get_file_mode: G) -> Result<Option<MatchType>, G::Error>
where where
P: AsRef<[u8]>, P: AsRef<[u8]>,
G: GetFileMode, G: GetFileMode,
{ {
// This is an &self method on a `T where T: 'a`.
let this: &'a Self = unsafe { std::mem::transmute(self) };
let mut get_file_mode = Some(get_file_mode); let mut get_file_mode = Some(get_file_mode);
let mut file_mode = None; let mut file_mode = None;
for m in this.into_iter().rev() { for m in self.into_iter().rev() {
if file_mode.is_none() && m.entry_needs_file_mode() { if file_mode.is_none() && m.entry_needs_file_mode() {
file_mode = Some(get_file_mode.take().unwrap().get()?); file_mode = Some(get_file_mode.take().unwrap().get()?);
} }
@ -457,18 +458,19 @@ where
Ok(None) Ok(None)
} }
fn matches_exact<P, G>(&self, path: P, get_file_mode: G) -> Result<Option<MatchType>, G::Error> fn matches_exact<P, G>(
&'a self,
path: P,
get_file_mode: G,
) -> Result<Option<MatchType>, G::Error>
where where
P: AsRef<[u8]>, P: AsRef<[u8]>,
G: GetFileMode, G: GetFileMode,
{ {
// This is an &self method on a `T where T: 'a`.
let this: &'a Self = unsafe { std::mem::transmute(self) };
let mut get_file_mode = Some(get_file_mode); let mut get_file_mode = Some(get_file_mode);
let mut file_mode = None; let mut file_mode = None;
for m in this.into_iter().rev() { for m in self.into_iter().rev() {
if file_mode.is_none() && m.entry_needs_file_mode() { if file_mode.is_none() && m.entry_needs_file_mode() {
file_mode = Some(get_file_mode.take().unwrap().get()?); file_mode = Some(get_file_mode.take().unwrap().get()?);
} }