{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreignlantlhfrpq7dijo23v3xa7sb5g5exvcj63mm3t4rvqwm4cfz6y",
"uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mkyuhlavur22"
},
"path": "/t/std-phantomunsized-marker-type/24219#post_1",
"publishedAt": "2026-05-04T02:20:52.000Z",
"site": "https://internals.rust-lang.org",
"textContent": "in `library/core/src/marker.rs`:\n\n\n /// A marker type without a compile-time or runtime defined size.\n ///\n /// This is distinct from other dynamically-sized types as it does not have\n /// pointer metadata. References/pointers to slices (`[T]`) and trait objects\n /// (`dyn Trait`) carry extra metadata (length for slices, vtable pointer for\n /// trait objects).\n ///\n /// This is useful for creating immovable structs, or structs with trailing data.\n ///\n /// Example:\n ///\n /// ```rust\n /// pub struct MyImmovableType {\n /// a: u32,\n /// b: f64,\n /// c: String,\n /// _unsized: PhantomUnsized,\n /// }\n ///\n /// // ...\n ///\n /// // A reference to `MyImmovableType` is \"thin\" like references to sized types.\n /// assert_eq!(size_of::<&MyImmovableType>(), size_of::<&()>());\n /// ```\n pub extern type PhantomUnsized;\n\n\nand to make it possible to construct these immovable types,\n\nin `library/core/src/mem/mod.rs`:\n\n\n /// Return the minimum size of a type in bytes.\n ///\n /// For unsized types, this is the size of the \"leading\" data before the unsized\n /// field. For sized types, this is equivalent to [`size_of`].\n ///\n /// ```rust\n /// pub struct MyTypeWithDST<T: ?Sized> {\n /// a: u32,\n /// b: f64,\n /// trailer: T,\n /// }\n ///\n /// assert_eq!(min_size_of::<MyTypeWithDST<[u32]>>(), 16);\n /// assert_eq!(min_size_of::<MyTypeWithDST<dyn Trait>>(), 16);\n /// assert_eq!(min_size_of::<MyTypeWithDST<PhantomUnsized>>(), 16);\n /// ```\n pub const fn min_size_of<T: ?Sized>() -> usize;\n\n // `min_align_of` is not needed as `align_of` already returns \"the ABI-required\n // minimum alignment of a type\". However, the type parameter on `align_of` needs\n // to be relaxed to `?Sized`. The documentation needs to be updated to specify\n // the behavior of `dyn Trait` since the actual alignment is defined at runtime.\n\n // The trait bound on `size_of` must be changed from `T: ?Sized` to\n // `T: ?MetaSized` so `size_of::<PhantomUnsized>()` results in a compiler error.\n\n\nThis replaces `extern type`; developers would use a newtype instead:\n\n\n pub struct MyExternType(PhantomUnsized);\n\n\nAttempting to \"move\" a runtime-unsized type with `std::ptr::copy_nonoverlapping` is generally undefined behavior _except_ when library invariants are satisfied. For example, a \"packet\" type with a `size` field and trailing bytes cannot be moved safely by another other library because its invariants (presence of trailing bytes within its allocation) may be violated.\n\nReferences to runtime-unsized types will not have the dereferenceable LLVM attribute (or maybe they could if it isn't UB to read past the end of a dereferenceable ptr).",
"title": "`std::marker::PhantomUnsized` marker type"
}