Pre-RFC: non-footgun non-static TypeId

I believe it does, in that it's the only way I know of in which such a feature has sound usecases.

IIUC your eq_ignoring_lifetimes means this is unsound:

// R => "runtime", S => "static"
fn try_cast<R, S: 'static>(r: R) -> Result<S, R> {
    if TypeId::of::<S>().eq_ignoring_lifetimes::<R>() {
        Ok(transmute(r)) // realistically, transmute_copy + forget
    } else {
        Err(r)
    }
}

If I do e.g. try_cast::<_, &'static str>(&"foo".to_string()) the above would return Ok("foo"), except pointing to the heap, so when the String is deallocated, you'll pretty much be guaranteed UB unless you get rid of/never access again the bad &'static str first.

But if it's limited to "all types with the ID are 'static" , then you would get Err because &'a str is only 'static when 'a is, not always (and AFAIK you can do casts like thing as long as you can guarantee that the types contain no lifetime positions, which is currently isomorphic to "always 'static").

This is the kind of usecase I was referencing in my earlier comment above, from which I linked https://github.com/sagebind/castaway/pull/6#issuecomment-1151011368.

3 Likes