Unbreakable covariance check

โš“ Rust    ๐Ÿ“… 2026-02-17    ๐Ÿ‘ค surdeus    ๐Ÿ‘๏ธ 6      

surdeus

A few crates like yoke and Lender perform covariance check on lifetimes using techniques using pointer assignment like

 fn __check_covariance<'__long: '__short, '__short>(
      p: *const T<'__long>,
  ) -> *const T<'__short>;

Implementing this method with { p } works only if T is covariant in its lifetime. If for some reason (e.g., manually-proven covariance) you want to bypass the check, you would like that the bypass requires an unsafe, and in this case unsafe { transmute { p } } will work.

The problem is that also core::ptr::null() will work, and there's no unsafe.

You can try to improve with

 fn __check_covariance<'__long: '__short, '__short>(
      p: &*const T<'__long>,
  ) -> &*const T<'__short>;

but you can get around with Box::leak(Box::new(null())).

Is there any way to write this type coercion so that the only alternatives to { p } for implementation are unsafe? Clearly Box::leak(Box::new(null())) denotes a strong user intentโ€”can't be a footgun like null()โ€”but, still, it would be nice if unsafe was necessary.

The problem is that there are many ways to wrap T in something whose argument is covariant (e.g., *const, Option, Vec, ...) but in all cases I can think you can conjure one of these out of thin air (core::ptr::null(), None, vec![], ...).

This is of course related to [Compiler support for statically asserting variance?].

2 posts - 1 participant

Read full topic

๐Ÿท๏ธ Rust_feed