Skip to main content

yoke/
utils.rs

1// This file is part of ICU4X. For terms of use, please see the file
2// called LICENSE at the top level of the ICU4X source tree
3// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5use crate::Yokeable;
6
7/// This method casts `yokeable` between `&'a mut Y<'static>` and `&'a mut Y<'a>`,
8/// and passes it to `f`.
9///
10/// See [`Yokeable::transform_mut`] for why this is safe, noting that no `'static` return type
11/// can leak data from the cart or Yokeable.
12#[inline]
13pub(crate) fn transform_mut_yokeable<'a, Y, F, R>(yokeable: &'a mut Y, f: F) -> R
14where
15    Y: Yokeable<'a>,
16    // be VERY CAREFUL changing this signature, it is very nuanced
17    F: 'static + for<'b> FnOnce(&'b mut Y::Output) -> R,
18    R: 'static,
19{
20    // Cast away the lifetime of `Y`
21    // Safety: this is equivalent to f(transmute(yokeable)), and the documentation of
22    // [`Yokeable::transform_mut`] and this function explain why doing so is sound.
23    let y = unsafe { &mut *(yokeable as *mut Y as *mut Y::Output).cast() };
24    f(y)
25}