The File, Mmap and ZipArchive types are not self-referential, so it does not make sense to pin them. If a Pin should go anywhere, it should be around your struct, but since you are pointing into memory owned by the struct, but not actually directly into the struct (i.e. moving the ZipCursor does not move the mmapped region), you do not gain anything from Pin whatsoever.
Actually, it does implement Unpin because all of its fields do. To opt-out, you need to add a field of type PhantomPinned.
If you want something that is at least close to a correct solution, it would look something like this:
// Order of fields is important to ensure that references are dropped before owner.
struct ZipCursor {
file: File,
archive: ZipArchive<'static>,
tree: DirectoryContents<'static>,
mmap: memmap::Mmap,
}
impl ZipCursor {
pub fn open_zip(file: File) -> Self {
let mmap = Mmap::map(&file).unwrap();
let (archive, tree) = create_archive(&mmap);
let (archive, tree) = unsafe { transmute_lifetimes(archive, tree) };
Self {
file,
archive,
tree,
mmap,
}
}
}
unsafe fn transmute_lifetimes(zip: ZipArchive<'a>, tree: DirectoryContents<'a>) -> (ZipArchive<'static>, DirectoryContents<'static>) {
let new_zip = std::mem::transmute::<ZipArchive<'a>, ZipArchive<'static>>(zip);
let new_tree = std::mem::transmute::<DirectoryContents<'a>, DirectoryContents<'static>>(tree);
(new_zip, new_tree)
}
fn create_archive<'a>(data: &'a [u8]) -> (ZipArchive<'a>, DirectoryContents<'a>) {
todo!()
}
Of course, you must be careful to never give out a static reference to the memmapped region. That would allow a use-after-free.