{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreid3weo22mhygadrztoqu2df7kejrypkpesyo6juhxuz4uol5zwsqu",
"uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mmarapi3f2w2"
},
"path": "/t/pre-rfc-improved-ergonomics-for/24336#post_8",
"publishedAt": "2026-05-19T14:09:30.000Z",
"site": "https://internals.rust-lang.org",
"tags": [
"(playground)"
],
"textContent": "robofinch:\n\n> Yes, this is an absurd scenario with a useless type, but it would then be _unsound_ to coerce `UninhabitedErr<T, !>` to a general `Uninhabited<T, E>` where `E` may be a non-ZST or inhabited type.\n\n(I just realise I'd overread what might be a typo ... assuming you meant coercing to a general _`UninhabitedErr<T,E>`_ ...)\n\nAre you talking about something like a less-naive version of this (playground):\n\n\n #![allow(unused_variables)]\n #![feature(never_type)]\n\n /// A wrapper around a result which is always OK. We rely on X being a ZST for\n /// various optimisations and functionality. (See SAFETY, below, for details on the\n /// consequences.)\n ///\n /// ## SAFETY\n /// - X must be a zero-sized type. We have no way to ensure that the compiler\n /// will validate this, so the constructor and .map_err() are both `unsafe`.\n pub struct Always<T, X>(Result<T, X>);\n\n impl<T, X> Always<T, X> {\n /// ## SAFETY\n /// - X must be a zero-sized type. When calling `new` you must guarantee that\n /// this is the case.\n pub unsafe fn new(t: T) -> Self {\n Self(Result::Ok(t))\n }\n\n pub fn map<F, U>(self, f: F) -> Always<U, X>\n where\n F: FnOnce(T) -> U,\n {\n Always(self.0.map(f))\n }\n\n /// Use map_err to change e.g. Always<String, !> to Always<String, Infallible>\n ///\n /// ## SAFETY\n /// - Z must be a zero-sized type. When calling `map_err` you must guarantee that\n /// this is the case.\n pub unsafe fn map_err<Z>(self) -> Always<T, Z> {\n unsafe { Always(Ok(self.0.unwrap_unchecked())) }\n }\n }\n\n pub enum ZST {}\n\n fn main() {\n let bang: Always<u32, !> = unsafe { Always::new(5) };\n let bang = bang.map(|x| x+1);\n let custom_zst: Always<u32, ZST> = unsafe { bang.map_err() };\n }\n\n\nIf so ... I can see how any attempt to fake a `map_err`-like function would invalidate the safety of the type.\n\nThe best, safe, way to manage that kind of situation may well be to restrict the feature to only converting `Try`-types which have a suitable implementation of `FromResidual`. I can't see a way to implement `Try` and `FromResidual` safely for the above example (anyone?).\n\nThat would cover the \"nested, no map / map is ugly\" cases and leave the trait-bound case as \"will be covered by the blanket `impl From<!> for T` at some point anyway, so don't try to overcomplicate things\".",
"title": "Pre-RFC improved ergonomics for `!`"
}