(I know I deleted a post, I just didn't finished writing it and I just realized too late I could just edit)

Guess what, I think I a bit too stubborn because I kept looking for a sound solution. Once again, I'm posting this here because *I want* people to break it.

Tell me if I'm wrong, but given two `Sized`

types `T`

and `U`

, having `T: U`

⇒ `T`

can be safely transmuted into `U`

. For example, `u32: u32`

so it's safe to transmute `u32`

into `u32`

. This is pretty obvious, but let's do it with references. `'a: 'b `

⇒ `&'a u32: &'b u32`

⇒ `&'a u32`

can be safely transmuted into `&'b u32`

.

This also work for contravariant and invariant lifetimes. `'T: U`

⇒ `fn(U): fn(T)`

⇒ `fn(U)`

can be safely transmuted into `fn(T)`

. Also, `Cell<T>: Cell<T>`

because `Cell<T>`

is invariant in `T`

.

If this is correct, then it should be possible to write somthing like this.

```
// Safety:
//
// `Self` must be a subtype of `T`.
unsafe trait SubtypeOf<T: ?Sized> {}
```

This trait can be implemented for any `T`

that doesn't have lifetime paramters.

```
unsafe impl SubtypeOf<u32> for u32 {}
```

And the reasoning I did above can be used here. Rust doesn't have a `T: U`

syntax but this is basically

the same thing.

```
// Safety:
//
// `&'a T` is covariant in `'a` so we have to require `'a: 'b`.
// `&'a T` is covariant in `T` so we have to require `T: U`.
unsafe impl<'a, 'b, U, T> SubtypeOf<&'b U> for &'a T
where
'a: 'b,
U: ?Sized,
T: ?Sized + SubtypeOf<U>,
{}
// Safety:
//
// `fn(T)` is contravariant in `T` so we have to require `U: T`.
unsafe impl<U, T> SubtypeOf<fn(U)> for fn(T)
where
U: SubtypeOf<T>,
{}
// Safety:
//
// This implementation requires `T` to be the same.
unsafe impl<T: ?Sized> SubtypeOf<Cell<T>> for Cell<T> {}
```

This pretty basic and not really useful. But this does mean that we can write a safe version of transmute.

```
/// Safely transmutes a `T` into an `U`.
fn safe_transmute<T, U>(value: T) -> U
where
T: SubtypeOf<U>
{
let value = std::mem::ManuallyDrop::new(value);
unsafe { (&*value as *const T as *const U).read() }
}
```

Our problem is that `TypeId`

equality completely forgets about lifetimes. But if we could somehow remember the type subtyping relationship of `T`

and `U`

regarding their lifetime parameters, it would be possible to write a fallible version of `safe_transmute`

.

Introducing: my new attempt.

```
/// # Safety
///
/// Let `F` be the type constructor of `Self`.
///
/// * `'cov` must be the lifetime of all covariant lifetime paramters of `F`.
/// * `'con` must be the lifetime of all contravariant lifetime parameters of `F`.
/// * `'inv` must be the lifetime of all invariant lifetime parameters of `F`.
pub unsafe trait Any<'cov, 'con, 'inv> {
fn type_id(&self) -> u64 { type_id::<Self>() }
}
```

From this, we can create our new `safe_transmute`

. Let's call it `checked_transmute`

.

```
/// Safely transmutes a `T` into an `U`.
fn checked_transmute<'cov_t, 'con_t, 'cov_u, 'con_u, 'inv, T, U>(value: T) -> Result<U, T>
where
T: Any<'cov_t, 'con_t, 'inv>,
U: Any<'cov_u, 'con_u, 'inv>,
'cov_t: 'cov_u,
'con_u: 'con_t,
{
if type_id::<T>() == type_id::<U>() {
let value = std::mem::ManuallyDrop::new(value);
// Safety:
//
// We know that T and U are equal in their IDs, meaning they can only
// differ in their lifetimes.
//
// The signature of the function ensures that `U: T` as long as they are the only
// only thing that differs is the lifetimes.
//
// This should be safe?
Ok(unsafe { std::ptr::read(&*value as *const T as *const U) })
} else {
Err(value)
}
}
```

The idea is that `TypeId`

equality only check for half the requirements of a safe transmutation. Keeping the other half in `Any`

's trait constructor (is that a thing ? A trait constructor ? You got it.)

If this function really is safe (and it probably isn't), then writing `downcast_ref`

and `downcast_mut`

is trivial.

This new `Any`

trait is basically a generalization of the old `OutlivedBy<'a>`

which only took covariant lifetimes in account.

Deriving `Any`

isn't very difficult, but it's not possible to write a blanket implementation for any `T`

with Rust's current syntax. Here is some examples (removed the `unsafe impl`

for clarity).

```
// Safety:
//
// `str` doesn have lifetime paramters. Any lifetime works for this type.
impl<'cov, 'con, 'inv> Any<'cov, 'con, 'inv> for str {}
// Safety:
//
// `&'a T` is covariant in `'a`, so we have to put `'cov` in its place.
// `&'a T` is covariant in `T`, so we simply have to forward the lifetimes.
impl<'cov, 'con, 'inv, T> Any<'cov, 'con, 'inv> for &'cov T
where
T: Any<'cov, 'con, 'inv>,
{}
// Safety:
//
// `Cell<T>` is invariant in `T`, so all the lifetimes of `T` have to be frozen.
impl<'cov, 'con, 'inv, T> Any<'cov, 'con, 'inv> for Cell<T>
where
T: Any<'inv, 'inv, 'inv>,
{}
// Safety:
//
// `fn(T)` is contravariant in `U`, so the lifetimes have to be forwarded to `T` by
// swapping the `'cov` and `'con` lifetimes.
impl<'cov, 'con, 'inv, T> Any<'cov, 'con, 'inv> for fn(T)
where
T: Any<'con, 'cov, 'inv>,
{}
```

Try it on the playground!