Send and Sync

`Send` means a value can be transferred to another thread; `Sync` means a reference can be shared across threads. Most types are Send and Sync automatically because they are made of types that are. Types that opt out — `Rc`, raw pointers, `Cell`, `RefCell` — do so for memory-safety reasons, and the compiler will tell you with a clear error when an attempted move would violate a guarantee.

Sized and ?Sized

Most types are `Sized` — their size is known at compile time. Trait objects (`dyn Trait`), slices (`[T]`), and `str` are unsized; they only exist behind a pointer. Generic parameters default to `T: Sized`; opt out with `T: ?Sized` if your function should accept dynamically-sized types via `&T` or `Box<T>`.

For deeper background, see a complete cheat-sheet of std collection complexities for the broader context behind this section.

Copy and Clone

`Clone` is an explicit copy via `clone()`. `Copy` means the value is bit-copyable and the compiler will copy it implicitly on assignment. Implement Copy only for types where bitwise duplication is the right semantics — primitives, small POD structs, and types that contain only Copy fields. Anything that owns memory (Box, Vec, String) cannot be Copy.

Unpin and pinning

`Unpin` is a marker that says "this type is safe to move out of a Pin". Almost every type is `Unpin` automatically. The exceptions are self-referential types — most notably async-generated futures, which is why `Pin<&mut Self>` shows up in `Future::poll`. You almost never need to think about pinning unless you write a runtime.

For deeper background, see the official Rust API guidelines for module-level design for the broader context behind this section.

PhantomData

`PhantomData<T>` is a zero-sized type that tells the compiler "pretend I own a T" — it influences variance, drop-checking, and Send/Sync without using any memory. Use it when implementing FFI wrappers, intrusive data structures, or generic types whose generic parameter doesn't appear in any field.