diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md
index 428f053ef..1b91188e8 100644
--- a/src/expressions/operator-expr.md
+++ b/src/expressions/operator-expr.md
@@ -338,7 +338,7 @@ well as the following additional casts. Here `*T` means either `*const T` or
 | Type of `e`           | `U`                   | Cast performed by `e as U`       |
 |-----------------------|-----------------------|----------------------------------|
 | Integer or Float type | Integer or Float type | Numeric cast                     |
-| C-like enum           | Integer type          | Enum cast                        |
+| Field-less enum       | Integer type          | Enum cast                        |
 | `bool` or `char`      | Integer type          | Primitive to integer cast        |
 | `u8`                  | `char`                | `u8` to `char` cast              |
 | `*T`                  | `*V` where `V: Sized` \* | Pointer to pointer cast       |
diff --git a/src/items/enumerations.md b/src/items/enumerations.md
index 258795503..f94c06d19 100644
--- a/src/items/enumerations.md
+++ b/src/items/enumerations.md
@@ -13,8 +13,8 @@
 >
 > _EnumItem_ :\
 > &nbsp;&nbsp; _OuterAttribute_<sup>\*</sup>\
-> &nbsp;&nbsp; [IDENTIFIER]&nbsp;( _EnumItemTuple_ | _EnumItemStruct_
->                                | _EnumItemDiscriminant_ )<sup>?</sup>
+> &nbsp;&nbsp; [IDENTIFIER]&nbsp;( _EnumItemTuple_ | _EnumItemStruct_ )<sup>?</sup>
+>                                _EnumItemDiscriminant_<sup>?</sup>
 >
 > _EnumItemTuple_ :\
 > &nbsp;&nbsp; `(` [_TupleFields_]<sup>?</sup> `)`
@@ -56,22 +56,68 @@ a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 };
 ```
 
 In this example, `Cat` is a _struct-like enum variant_, whereas `Dog` is simply
-called an enum variant. Each enum instance has a _discriminant_ which is an
-integer associated to it that is used to determine which variant it holds. An
-opaque reference to this discriminant can be obtained with the
-[`mem::discriminant`] function.
+called an enum variant.
 
-## Custom Discriminant Values for Field-Less Enumerations
+## Discriminants
 
-If there is no data attached to *any* of the variants of an enumeration,
-then the discriminant can be directly chosen and accessed.
+Each enum instance has a _discriminant_: an integer logically associated to it
+that is used to determine which variant it holds. An opaque reference to this
+discriminant can be obtained with the [`mem::discriminant`] function.
 
-These enumerations can be cast to integer types with the `as` operator by a
-[numeric cast]. The enumeration can optionally specify which integer each
-discriminant gets by following the variant name with `=` followed by a [constant
-expression]. If the first variant in the declaration is unspecified, then it is
-set to zero. For every other unspecified discriminant, it is set to one higher
-than the previous variant in the declaration.
+Under the [default representation], the discriminant is interpreted as
+an `isize` value. However, the compiler is allowed to use a smaller type (or
+another means of distinguishing variants) in its actual memory layout.
+
+If the [primitive representation] or the [`C` representation] is used, the
+leading bytes of a variant (for example, two bytes if `#[repr(u16)]` is used), will
+correspond exactly to the discriminant.
+
+### Assigning Discriminant Values
+
+#### Explicit Discriminants
+
+In two circumstances, the discriminant of a variant may be explicitly set by
+following the variant name with `=` and a [constant expression]:
+
+<ol>
+<li>
+
+if the enumeration is "C-like" (i.e., it has no tuple or struct variants); e.g.:
+
+```rust
+# #![feature(arbitrary_enum_discriminant)]
+enum Enum {
+    Foo = 3,
+    Bar = 2,
+    Baz = 1,
+}
+```
+</li>
+<li>
+
+if a [primitive representation] is used. For example:
+
+```rust
+# #![feature(arbitrary_enum_discriminant)]
+#[repr(u8)]
+enum Enum {
+    Unit = 3,
+    Tuple(u16),
+    Struct {
+        a: u8,
+        b: u16,
+    } = 1,
+}
+```
+</li>
+</ol>
+
+#### Implicit Discriminants
+
+If a discriminant for a variant is not specified, then it is set to one higher
+than the discriminant of the previous variant in the declaration. If the
+discriminant of the first variant in the declaration is unspecified, then
+it is set to zero.
 
 ```rust
 enum Foo {
@@ -84,14 +130,11 @@ let baz_discriminant = Foo::Baz as u32;
 assert_eq!(baz_discriminant, 123);
 ```
 
-Under the [default representation], the specified discriminant is interpreted as
-an `isize` value although the compiler is allowed to use a smaller type in the
-actual memory layout. The size and thus acceptable values can be changed by
-using a [primitive representation] or the [`C` representation].
+#### Restrictions
 
 It is an error when two variants share the same discriminant.
 
-```rust,ignore
+```rust,compile_fail
 enum SharedDiscriminantError {
     SharedA = 1,
     SharedB = 1
@@ -107,7 +150,7 @@ enum SharedDiscriminantError2 {
 It is also an error to have an unspecified discriminant where the previous
 discriminant is the maximum value for the size of the discriminant.
 
-```rust,ignore
+```rust,compile_fail
 #[repr(u8)]
 enum OverflowingDiscriminantError {
     Max = 255,
@@ -122,6 +165,53 @@ enum OverflowingDiscriminantError2 {
 }
 ```
 
+### Accessing Discriminant Values
+
+#### Casting
+
+If there is no data attached to *any* of the variants of an enumeration, then
+the discriminant can be directly accessed with a [numeric cast]; e.g.:
+
+```rust
+enum Enum {
+    Unit,
+    Tuple(),
+    Struct{},
+}
+
+assert_eq!(0, Enum::Unit as isize);
+assert_eq!(1, Enum::Tuple() as isize);
+assert_eq!(2, Enum::Struct{} as isize);
+```
+
+#### Pointer Casting
+
+If the enumeration specifies a [primitive representation], then the
+discriminant may be reliably accessed via unsafe pointer casting:
+
+```rust
+#[repr(u8)]
+enum Enum {
+    Unit,
+    Tuple(bool),
+    Struct{a: bool},
+}
+
+impl Enum {
+    fn discriminant(&self) -> u8 {
+        unsafe { *(self as *const Self as *const u8) }
+    }
+}
+
+let unit_like = Enum::Unit;
+let tuple_like = Enum::Tuple(true);
+let struct_like = Enum::Struct{a: false};
+
+assert_eq!(0, unit_like.discriminant());
+assert_eq!(1, tuple_like.discriminant());
+assert_eq!(2, struct_like.discriminant());
+```
+
 ## Zero-variant Enums
 
 Enums with zero variants are known as *zero-variant enums*. As they have
diff --git a/src/type-layout.md b/src/type-layout.md
index fe611559f..e2cf0af60 100644
--- a/src/type-layout.md
+++ b/src/type-layout.md
@@ -357,7 +357,7 @@ used with any other representation.
 [`size_of`]: ../std/mem/fn.size_of.html
 [`Sized`]: ../std/marker/trait.Sized.html
 [dynamically sized types]: dynamically-sized-types.html
-[C-like enumerations]:  items/enumerations.html#custom-discriminant-values-for-field-less-enumerations
+[C-like enumerations]:  items/enumerations.html#explicit-discriminants
 [zero-variant enumerations]: items/enumerations.html#zero-variant-enums
 [undefined behavior]: behavior-considered-undefined.html
 [27060]: https://github.com/rust-lang/rust/issues/27060