Skip to content

Commit ef15971

Browse files
authored
Merge pull request rust-lang#101 from matthewjasper/type-cleanup
Types chapter cleanup and new sections
2 parents d8dfa75 + 1b7416e commit ef15971

File tree

4 files changed

+297
-143
lines changed

4 files changed

+297
-143
lines changed

src/SUMMARY.md

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232

3333
- [Type system](type-system.md)
3434
- [Types](types.md)
35+
- [Dynamically Sized Types](dynamically-sized-types.md)
36+
- [Interior mutability](interior-mutability.md)
3537
- [Subtyping](subtyping.md)
3638
- [Type coercions](type-coercions.md)
3739

src/dynamically-sized-types.md

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Dynamically Sized Types
2+
3+
Most types have a fixed size that is known at compile time and implement the
4+
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.
6+
[Slices] and [trait objects] are two examples of <abbr title="dynamically sized
7+
types">DSTs</abbr>. Such types can only be used in certain cases:
8+
9+
* [Pointer types] to <abbr title="dynamically sized types">DSTs</abbr> are
10+
sized but have twice the size of pointers to sized types
11+
* Pointers to slices also store the number of elements of the slice.
12+
* Pointers to trait objects also store a pointer to a vtable.
13+
* <abbr title="dynamically sized types">DSTs</abbr> can be provided as
14+
type arguments when a bound of `?Sized`. By default any type parameter
15+
has a `?Sized` bound.
16+
* Traits may be implemented for <abbr title="dynamically sized
17+
types">DSTs</abbr>. Unlike type parameters`Self: ?Sized` by default in trait
18+
definitions.
19+
* Structs may contain a <abbr title="dynamically sized type">DST</abbr> as the
20+
last field, this makes the struct itself a
21+
<abbr title="dynamically sized type">DST</abbr>.
22+
23+
Notably: [variables], function parameters, [const] and [static] items must be
24+
`Sized`.
25+
26+
[sized]: the-sized-trait.html
27+
[Slices]: #array-and-slice-types
28+
[trait objects]: #trait-objects
29+
[Pointer types]: #pointer-types
30+
[variables]: variables.html
31+
[const]: items.html#constant-items
32+
[static]: items.html#static-items

src/interior-mutability.md

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Interior Mutability
2+
3+
Sometimes a type needs be mutated while having multiple aliases, in Rust this
4+
is achieved using a pattern called _interior mutability_. A type has interior
5+
mutability if its internal state can be changed through a [shared reference] to
6+
it. This goes against the usual [requirement][ub] that the value pointed to by a
7+
shared reference is not mutated.
8+
9+
[`std::cell::UnsafeCell<T>`] type is the only legal way in Rust to disable this
10+
requirement. When `UnsafeCell<T>` is immutably aliased, it is still safe to
11+
mutate, or obtain a mutable reference to, the `T` it contains. As with all
12+
other types, it is undefined behavior to have multiple `&mut UnsafeCell<T>`
13+
aliases.
14+
15+
Other types with interior mutability can be created by using `UnsafeCell<T>` as
16+
a field. The standard library provides a variety of types that provide safe
17+
interior mutability APIs. For example, [`std::cell::RefCell<T>`] uses run-time
18+
borrow checks to ensure the usual rules around multiple references. The
19+
[`std::sync::atomic`] module contains types that wrap a value that is only
20+
accessed with atomic operations, allowing the value to be shared and mutated
21+
across threads.
22+
23+
[shared reference]: types.hmtl#shared-references
24+
[ub]: behavior-considered-undefined.html
25+
[`std::mem::transmute`]: ../std/mem/fn.transmute.html
26+
[`std::cell::UnsafeCell<T>`]: ../std/cell/struct.UnsafeCell.html
27+
[`std::cell::RefCell<T>`]: ../std/cell/struct.RefCell.html
28+
[`std::sync::atomic`]: ../std/sync/atomic.html
29+
30+

0 commit comments

Comments
 (0)