{
  "$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"
}