Skip to content

Commit d812ea2

Browse files
authored
Merge pull request #156 from Havvy/reprs
New Section - Type Layout
2 parents 32fc52b + c19106d commit d812ea2

File tree

7 files changed

+377
-27
lines changed

7 files changed

+377
-27
lines changed

src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
- [Type system](type-system.md)
6262
- [Types](types.md)
6363
- [Dynamically Sized Types](dynamically-sized-types.md)
64+
- [Type layout](type-layout.md)
6465
- [Interior mutability](interior-mutability.md)
6566
- [Subtyping](subtyping.md)
6667
- [Type coercions](type-coercions.md)

src/attributes.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ pub mod m3 {
357357
}
358358
```
359359

360-
### Inline attributes
360+
### Inline attribute
361361

362362
The inline attribute suggests that the compiler should place a copy of
363363
the function or static in the caller, rather than generating code to

src/dynamically-sized-types.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Most types have a fixed size that is known at compile time and implement the
44
trait [`Sized`][sized]. A type with a size that is known only at run-time is
5-
called a _dynamically sized type_ (_DST_) or (informally) an unsized type.
5+
called a _dynamically sized type_ (_DST_) or, informally, an unsized type.
66
[Slices] and [trait objects] are two examples of <abbr title="dynamically sized
77
types">DSTs</abbr>. Such types can only be used in certain cases:
88

src/glossary.md

+22
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
An ‘abstract syntax tree’, or ‘AST’, is an intermediate representation of
66
the structure of the program when the compiler is compiling it.
77

8+
### Alignment
9+
10+
The alignment of a value specifies what addresses values are preferred to
11+
start at. Always a power of two. References to a value must be aligned.
12+
[More][alignment].
13+
814
### Arity
915

1016
Arity refers to the number of arguments a function or operator takes.
@@ -69,6 +75,21 @@ Types that can be referred to by a path directly. Specifically [enums],
6975
Prelude, or The Rust Prelude, is a small collection of items - mostly traits - that are
7076
imported into very module of every crate. The traits in the prelude are pervasive.
7177

78+
### Size
79+
80+
The size of a value has two definitions.
81+
82+
The first is that it is how much memory must be allocated to store that value.
83+
84+
The second is that it is the offset in bytes between successive elements in an
85+
array with that item type.
86+
87+
It is a multiple of the alignment, including zero. The size can change
88+
depending on compiler version (as new optimizations are made) and target
89+
platform (similar to how `usize` varies per-platform).
90+
91+
[More][alignment].
92+
7293
### Slice
7394

7495
A slice is dynamically-sized view into a contiguous sequence, written as `[T]`.
@@ -104,6 +125,7 @@ It allows a type to make certain promises about its behavior.
104125

105126
Generic functions and generic structs can use traits to constrain, or bound, the types they accept.
106127

128+
[alignment]: type-layout.html#size-and-alignment
107129
[enums]: items/enumerations.html
108130
[structs]: items/structs.html
109131
[unions]: items/unions.html

src/items/enumerations.md

+63-23
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,9 @@
2525
> _EnumItemDiscriminant_ :
2626
> &nbsp;&nbsp; `=` [_Expression_]
2727
28-
An _enumeration_ is a simultaneous definition of a nominal [enumerated type] as
29-
well as a set of *constructors*, that can be used to create or pattern-match
30-
values of the corresponding enumerated type.
31-
32-
[enumerated type]: types.html#enumerated-types
28+
An *enumeration*, also referred to as *enum* is a simultaneous definition of a
29+
nominal [enumerated type] as well as a set of *constructors*, that can be used
30+
to create or pattern-match values of the corresponding enumerated type.
3331

3432
Enumerations are declared with the keyword `enum`.
3533

@@ -45,11 +43,11 @@ let mut a: Animal = Animal::Dog;
4543
a = Animal::Cat;
4644
```
4745

48-
Enumeration constructors can have either named or unnamed fields:
46+
Enum constructors can have either named or unnamed fields:
4947

5048
```rust
5149
enum Animal {
52-
Dog (String, f64),
50+
Dog(String, f64),
5351
Cat { name: String, weight: f64 },
5452
}
5553

@@ -59,45 +57,87 @@ a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 };
5957

6058
In this example, `Cat` is a _struct-like enum variant_, whereas `Dog` is simply
6159
called an enum variant. Each enum instance has a _discriminant_ which is an
62-
integer associated to it that is used to determine which variant it holds.
60+
integer associated to it that is used to determine which variant it holds. An
61+
opaque reference to this discriminant can be obtained with the
62+
[`mem::discriminant`] function.
6363

6464
## Custom Discriminant Values for Field-Less Enumerations
6565

6666
If there is no data attached to *any* of the variants of an enumeration,
6767
then the discriminant can be directly chosen and accessed.
6868

69-
If a discriminant isn't specified, they start at zero, and add one for each
70-
variant, in order. Each enum value is just its discriminant which you can
71-
specify explicitly:
69+
These enumerations can be cast to integer types with the `as` operator by a
70+
[numeric cast]. The enumeration can optionaly specify which integer each
71+
discriminant gets by following the variant name with `=` and then an integer
72+
literal. If the first variant in the declaration is unspecified, then it is set
73+
to zero. For every unspecified discriminant, it is set to one higher than the
74+
previous variant in the declaration.
7275

7376
```rust
7477
enum Foo {
7578
Bar, // 0
76-
Baz = 123,
79+
Baz = 123, // 123
7780
Quux, // 124
7881
}
82+
83+
let baz_discriminant = Foo::Baz as u32;
84+
assert_eq!(baz_discriminant, 123);
7985
```
8086

81-
The right hand side of the specification is interpreted as an `isize` value,
82-
but the compiler is allowed to use a smaller type in the actual memory layout.
83-
The [`repr` attribute] can be added in order to change the type of the right
84-
hand side and specify the memory layout.
87+
Under the [default representation], the specified discriminant is interpreted as
88+
an `isize` value although the compiler is allowed to use a smaller type in the
89+
actual memory layout. The size and thus acceptable values can be changed by
90+
using a [primitive representation] or the [`C` representation].
8591

86-
[`repr` attribute]: attributes.html#ffi-attributes
92+
It is an error when two variants share the same discriminant.
8793

88-
You can also cast a field-less enum to get its discriminant:
94+
```rust,ignore
95+
enum SharedDiscriminantError {
96+
SharedA = 1,
97+
SharedB = 1
98+
}
8999
90-
```rust
91-
# enum Foo { Baz = 123 }
92-
let x = Foo::Baz as u32; // x is now 123u32
100+
enum SharedDiscriminantError2 {
101+
Zero, // 0
102+
One, // 1
103+
OneToo = 1 // 1 (collision with previous!)
104+
}
93105
```
94106

95-
This only works as long as none of the variants have data attached. If it were
96-
`Baz(i32)`, this is disallowed.
107+
It is also an error to have an unspecified discriminant where the previous
108+
discriminant is the maximum value for the size of the discriminant.
109+
110+
```rust,ignore
111+
#[repr(u8)]
112+
enum OverflowingDiscriminantError {
113+
Max = 255,
114+
MaxPlusOne // Would be 256, but that overflows the enum.
115+
}
116+
117+
#[repr(u8)]
118+
enum OverflowingDiscriminantError2 {
119+
MaxMinusOne = 254, // 254
120+
Max, // 255
121+
MaxPlusOne // Would be 256, but that overflows the enum.
122+
}
123+
```
124+
125+
## Zero-variant Enums
126+
127+
Enums with zero variants are known as *zero-variant enums*. As they have
128+
no valid values, they cannot be instantiated.
129+
130+
```rust
131+
enum ZeroVariants {}
132+
```
97133

98134
[IDENTIFIER]: identifiers.html
99135
[_Generics_]: items.html#type-parameters
100136
[_WhereClause_]: items.html#type-parameters
101137
[_Expression_]: expressions.html
102138
[_TupleFields_]: items/structs.html
103139
[_StructFields_]: items/structs.html
140+
[enumerated type]: types.html#enumerated-types
141+
[`mem::discriminant`]: std/mem/fn.discriminant.html
142+
[numeric cast]: expressions/operator-expr.html#semantics
143+
[`repr` attribute]: attributes.html#ffi-attributes

0 commit comments

Comments
 (0)