From b35b7cd01baa9075b3dee192e80cda0b6bca0574 Mon Sep 17 00:00:00 2001 From: Taeer Bar-Yam Date: Fri, 13 Oct 2023 14:05:34 -0400 Subject: [PATCH] explicitly annotate lifetimes when unsafe is involved --- core/src/environment.rs | 4 ++-- core/src/identifier.rs | 11 +++++++---- core/src/term/array.rs | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/core/src/environment.rs b/core/src/environment.rs index e7aebec1ef..702d842259 100644 --- a/core/src/environment.rs +++ b/core/src/environment.rs @@ -100,7 +100,7 @@ impl Environment { /// Creates an iterator that visits all layers from the most recent one to the oldest. /// The element iterator type is `Rc>`. - pub fn iter_layers(&self) -> EnvLayerIter<'_, K, V> { + pub fn iter_layers<'slf>(&'slf self) -> EnvLayerIter<'slf, K, V> { EnvLayerIter { env: if !self.was_cloned() { Some(NonNull::from(self)) @@ -121,7 +121,7 @@ impl Environment { /// the most recent one. It uses this order, so calling `collect` on this iterator to create a /// hashmap would have the same values as the Environment. The element iterator type is `(&'env /// K, &'env V)`, with `'env` being the lifetime of the Environment. - pub fn iter_elems(&self) -> EnvElemIter<'_, K, V> { + pub fn iter_elems<'slf>(&'slf self) -> EnvElemIter<'slf, K, V> { let mut env: Vec>> = self .iter_layers() // SAFETY: Rc::as_ptr never returnes null diff --git a/core/src/identifier.rs b/core/src/identifier.rs index d3d4caae3b..b999905c96 100644 --- a/core/src/identifier.rs +++ b/core/src/identifier.rs @@ -258,12 +258,12 @@ mod interner { /// /// This operation cannot fails since the only way to have a [Symbol] is to have /// [interned](Interner::intern) the corresponding string first. - pub(crate) fn lookup(&self, sym: Symbol) -> &str { + pub(crate) fn lookup<'slf>(&'slf self, sym: Symbol) -> &'slf str { // SAFETY: We are making the returned &str lifetime the same as our struct, // which is okay here since the InnerInterner uses a typed_arena which prevents // deallocations, so the reference will be valid while the InnerInterner exists, // hence while the struct exists. - unsafe { std::mem::transmute(self.0.read().unwrap().lookup(sym)) } + unsafe { std::mem::transmute::<&'_ str, &'slf str>(self.0.read().unwrap().lookup(sym)) } } } @@ -300,8 +300,11 @@ mod interner { // It is also okay to use it from inside the mutex, since typed_arena does not allow // deallocation, so references are valid until the arena drop, which is tied to the // struct drop. + // XXX: we have to use &'a str here, not &'self str like the comment indicates. what's going on? let in_string = unsafe { - std::mem::transmute(self.arena.lock().unwrap().alloc_str(string.as_ref())) + std::mem::transmute::<&'_ str, &'a str>( + self.arena.lock().unwrap().alloc_str(string.as_ref()), + ) }; let sym = Symbol(self.vec.len() as u32); self.vec.push(in_string); @@ -312,7 +315,7 @@ mod interner { /// /// This operation cannot fails since the only way to have a [Symbol] /// is to have [interned](InnerInterner::intern) the corresponding string first. - fn lookup(&self, sym: Symbol) -> &str { + fn lookup<'slf>(&'slf self, sym: Symbol) -> &'slf str { self.vec[sym.0 as usize] } } diff --git a/core/src/term/array.rs b/core/src/term/array.rs index 88bcdc0d71..bcc9d99d17 100644 --- a/core/src/term/array.rs +++ b/core/src/term/array.rs @@ -160,7 +160,7 @@ impl IntoIterator for Array { // Otherwise, we clone everything. unsafe { - let mut inner: Rc<[ManuallyDrop]> = transmute(self.inner); + let mut inner = transmute::, Rc<[ManuallyDrop]>>(self.inner); let idx = self.start; let end = self.end;