Skip to content

Commit 8e84487

Browse files
committed
Add some missing sections to the types chapter
1 parent 729851f commit 8e84487

File tree

1 file changed

+85
-15
lines changed

1 file changed

+85
-15
lines changed

src/types.md

Lines changed: 85 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ Tuple types and values are denoted by listing the types or values of their
9393
elements, respectively, in a parenthesized, comma-separated list.
9494

9595
Because tuple elements don't have a name, they can only be accessed by
96-
pattern-matching or by using `N` directly as a field to access the
97-
`N`th element.
96+
pattern-matching or by using `N` directly as a field to access the `N`th
97+
element.
9898

9999
An example of a tuple type and its use:
100100

@@ -162,13 +162,13 @@ expression](expressions.html#struct-expressions).
162162

163163
The memory layout of a `struct` is undefined by default to allow for compiler
164164
optimizations like field reordering, but it can be fixed with the
165-
`#[repr(...)]` attribute. In either case, fields may be given in any order in
166-
a corresponding struct *expression*; the resulting `struct` value will always
165+
`#[repr(...)]` attribute. In either case, fields may be given in any order in a
166+
corresponding struct *expression*; the resulting `struct` value will always
167167
have the same memory layout.
168168

169169
The fields of a `struct` may be qualified by [visibility
170-
modifiers](visibility-and-privacy.html), to allow access to data in a
171-
struct outside a module.
170+
modifiers](visibility-and-privacy.html), to allow access to data in a struct
171+
outside a module.
172172

173173
A _tuple struct_ type is just like a struct type, except that the fields are
174174
anonymous.
@@ -178,9 +178,6 @@ The one value constructed by the associated [struct
178178
expression](expressions.html#struct-expressions) is the only value that
179179
inhabits such a type.
180180

181-
[^structtype]: `struct` types are analogous to `struct` types in C, the
182-
*record* types of the ML family, or the *struct* types of the Lisp family.
183-
184181
[^structtype]: `struct` types are analogous to `struct` types in C, the
185182
*record* types of the ML family, or the *struct* types of the Lisp family.
186183

@@ -202,6 +199,21 @@ corresponding `enum` type, as well as the size needed to store a discriminant.
202199
Enum types cannot be denoted *structurally* as types, but must be denoted by
203200
named reference to an [`enum` item](items.html#enumerations).
204201

202+
[^enumtype]: The `enum` type is analogous to a `data` constructor declaration in
203+
ML, or a *pick ADT* in Limbo.
204+
205+
## Union types
206+
207+
A *union type* is a nominal, heterogeneous C-like union, denoted by the name of
208+
a [`union` item](items.html#unions).
209+
210+
A union contains the value of any one of its fields. Since the accessing the
211+
wrong field can cause unexpected or undefined behaviour, it requires `unsafe`,
212+
except for initializing a union and writing `Copy` fields.
213+
214+
The memory layout of a `union` is undefined by default, but the `#[repr(...)]`
215+
attribute can be used to fix a layout.
216+
205217
[^enumtype]: The `enum` type is analogous to a `data` constructor declaration in
206218
ML, or a *pick ADT* in Limbo.
207219

@@ -252,6 +264,12 @@ operation: it involves only copying the pointer itself, that is, pointers are
252264
referencing of a [temporary value](expressions.html#temporary-lifetimes) will
253265
keep it alive during the scope of the reference itself.
254266

267+
### Mutable references (`&mut`)
268+
269+
These also point to memory owned by some other value. A mutable reference type
270+
is written `&mut type` or `&'a mut type`. A mutable reference (that hasn't been
271+
borrowed) is the only way to access the value it points to, so is not `Copy`.
272+
255273
### Raw pointers (`*const` and `*mut`)
256274

257275
Raw pointers are pointers without safety or liveness guarantees. Raw pointers
@@ -368,9 +386,9 @@ more of the closure traits:
368386
moved in the body of the closure. `Fn` inherits from `FnMut`, which itself
369387
inherits from `FnOnce`.
370388

371-
Closures that don't use anything from their environment ("non capturing closures")
372-
can be coerced to function pointers (`fn`) with the matching signature.
373-
To adopt the example from the section above:
389+
Closures that don't use anything from their environment ("non capturing
390+
closures") can be coerced to function pointers (`fn`) with the matching
391+
signature. To adopt the example from the section above:
374392

375393
```rust
376394
let add = |x, y| x + y;
@@ -385,9 +403,9 @@ x = bo(5,7);
385403
## Trait objects
386404

387405
In Rust, trait names also refer to [dynamically sized types] called _trait
388-
objects_. Like all DSTs, trait objects are used behind some kind of pointer:
389-
`&SomeTrait` or `Box<SomeTrait>`. Each instance of a pointer to a trait object
390-
includes:
406+
objects_. Like all <abbr title="dynamically sized types">DSTs</abbr>, trait
407+
objects are used behind some kind of pointer: `&SomeTrait` or `Box<SomeTrait>`.
408+
Each instance of a pointer to a trait object includes:
391409

392410
- a pointer to an instance of a type `T` that implements `SomeTrait`
393411
- a _virtual method table_, often just called a _vtable_, which contains, for
@@ -490,6 +508,58 @@ objects of type `Ref<'a, SomeTrait>` are the same as `Ref<'a, (SomeTrait +
490508
example in `std::rc::Rc<T>`.
491509

492510

511+
## Dynamically sized types
512+
513+
Most types have a fixed size that is known at compile time and implement the
514+
trait [`Sized`][sized] A type with a size that is known only at run-time is called a
515+
_dynamically sized type_ (_DST_) or unsized type. [Slices] and [trait objects]
516+
are two examples of <abbr title="dynamically sized types">DSTs</abbr>. Such
517+
types can only be used in certain cases:
518+
519+
* [Pointer types] to <abbr title="dynamically sized types">DSTs</abbr> are
520+
sized but have twice the size of pointers to sized types
521+
* Pointers to slices also store the number of elements of the slice.
522+
* Pointers to trait objects also store a pointer to a vtable.
523+
* <abbr title="dynamically sized types">DSTs</abbr> can be used as type
524+
parameters with a bound of `?Sized`
525+
* Traits may be implemented for <abbr title="dynamically sized
526+
types">DSTs</abbr>. Unlike [elsewhere][sized] `Self: ?Sized` by default in trait
527+
definitions.
528+
* Structs may contain a <abbr title="dynamically sized type">DST</abbr> as the
529+
last field, this makes the struct itself a
530+
<abbr title="dynamically sized type">DST</abbr>.
531+
532+
Notably: [variables], function parameters, [const] and [static] items must be
533+
sized.
534+
535+
[sized]: the-sized-trait.html
536+
[Slices]: #array-and-slice-types
537+
[trait objects]: #trait-objects
538+
[Pointer types]: #pointer-types
539+
[variables]: variables.html
540+
[const]: items.html#constant-items
541+
[static]: items.html#static-items
542+
543+
## Interior mutability
544+
545+
References prevent a value being both aliased and mutated: mutable references
546+
don't allow a value to be aliased and shared references prevent a value from
547+
being mutated. Sometimes this is too restrictive. The type
548+
[`std::cell::UnsafeCell<T>`](../std/cell/struct.UnsafeCell.html) provides an
549+
unsafe API that allows a type to own a `T` that can be mutated through a shared
550+
reference to the `UnsafeCell`. It is undefined behavior to have multiple `&mut
551+
UnsafeCell<T>` aliases.
552+
553+
The standard library provides a variety of different types that safely wrap
554+
this functionality. For example [`std::cell::RefCell<T>`] uses run-time borrow
555+
checks to ensure the usual rules around multiple references. The
556+
[`std::sync::atomic`] module contains types that wrap a value that is only
557+
accessed with atomic operations, allowing the value to be shared and mutated
558+
across threads.
559+
560+
[`std::cell::RefCell<T>`]: ../std/cell/struct.RefCell.html
561+
[`std::sync::atomic`]: ../std/sync/atomic.html
562+
493563
## Type parameters
494564

495565
Within the body of an item that has type parameter declarations, the names of

0 commit comments

Comments
 (0)