+There are three major categories of safe cast: explicit coercions, casts
+between numeric types, and pointer casts.
+
+Casting is not transitive: even if `e as U1 as U2` is a valid
+expression, `e as U2` is not necessarily so (in fact it will only be valid if
+`U1` coerces to `U2`).
+
+
+## Explicit coercions
+
+A cast `e as U` is valid if `e` has type `T` and `T` *coerces* to `U`.
+
+For example:
+
+```rust
+let a = "hello";
+let b = a as String
+```
+
+Coercions always occur implicitly so this form is only for clarity.
+
+## Numeric casts
+
+A cast `e as U` is also valid in any of the following cases:
+
+ * `e` has type `T` and `T` and `U` are any numeric types; *numeric-cast*
+ * `e` is a C-like enum and `U` is an integer type; *enum-cast*
+ * `e` has type `bool` or `char` and `U` is an integer; *prim-int-cast*
+ * `e` has type `u8` and `U` is `char`; *u8-char-cast*
+
+For example
+
+```rust
+let one = true as u8;
+let at_sign = 64 as char;
+```
+
+## Pointer casts
+
+Perhaps surprisingly, it is safe to cast pointers to and from integers, and
+to cast between pointers to different types subject to some constraints. It
+is only unsafe to dereference the pointer.
+
+* `e` has type `*T`, `U` is a pointer to `*U_0`, and either `U_0: Sized` or
+ unsize_kind(`T`) = unsize_kind(`U_0`); a *ptr-ptr-cast*
+* `e` has type `*T` and `U` is a numeric type, while `T: Sized`; *ptr-addr-cast*
+* `e` is an integer and `U` is `*U_0`, while `U_0: Sized`; *addr-ptr-cast*
+* `e` has type `&[T; n]` and `U` is `*const T`; *array-ptr-cast*
+* `e` is a function pointer type and `U` has type `*T`,
+ while `T: Sized`; *fptr-ptr-cast*
+* `e` is a function pointer type and `U` is an integer; *fptr-addr-cast*
+
+
+# `transmute`
+
+`as` only allows safe casting, and will for example reject an attempt to
+cast four bytes into a `u32`: