Skip to content

Commit

Permalink
explicitly annotate lifetimes when unsafe is involved
Browse files Browse the repository at this point in the history
  • Loading branch information
Radvendii committed Nov 6, 2023
1 parent 28672ee commit b35b7cd
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 7 deletions.
4 changes: 2 additions & 2 deletions core/src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl<K: Hash + Eq, V: PartialEq> Environment<K, V> {

/// Creates an iterator that visits all layers from the most recent one to the oldest.
/// The element iterator type is `Rc<HashMap<K, V>>`.
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))
Expand All @@ -121,7 +121,7 @@ impl<K: Hash + Eq, V: PartialEq> Environment<K, V> {
/// 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<NonNull<HashMap<K, V>>> = self
.iter_layers()
// SAFETY: Rc::as_ptr never returnes null
Expand Down
11 changes: 7 additions & 4 deletions core/src/identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)) }
}
}

Expand Down Expand Up @@ -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);
Expand All @@ -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]
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/term/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl IntoIterator for Array {
// Otherwise, we clone everything.

unsafe {
let mut inner: Rc<[ManuallyDrop<RichTerm>]> = transmute(self.inner);
let mut inner = transmute::<Rc<[RichTerm]>, Rc<[ManuallyDrop<RichTerm>]>>(self.inner);
let idx = self.start;
let end = self.end;

Expand Down

0 comments on commit b35b7cd

Please sign in to comment.