Skip to content

Commit

Permalink
Merge pull request rust-lang#101 from matthewjasper/type-cleanup
Browse files Browse the repository at this point in the history
Types chapter cleanup and new sections
  • Loading branch information
Havvy authored Sep 22, 2017
2 parents d8dfa75 + 1b7416e commit ef15971
Show file tree
Hide file tree
Showing 4 changed files with 297 additions and 143 deletions.
2 changes: 2 additions & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

- [Type system](type-system.md)
- [Types](types.md)
- [Dynamically Sized Types](dynamically-sized-types.md)
- [Interior mutability](interior-mutability.md)
- [Subtyping](subtyping.md)
- [Type coercions](type-coercions.md)

Expand Down
32 changes: 32 additions & 0 deletions src/dynamically-sized-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Dynamically Sized Types

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

* [Pointer types] to <abbr title="dynamically sized types">DSTs</abbr> are
sized but have twice the size of pointers to sized types
* Pointers to slices also store the number of elements of the slice.
* Pointers to trait objects also store a pointer to a vtable.
* <abbr title="dynamically sized types">DSTs</abbr> can be provided as
type arguments when a bound of `?Sized`. By default any type parameter
has a `?Sized` bound.
* Traits may be implemented for <abbr title="dynamically sized
types">DSTs</abbr>. Unlike type parameters`Self: ?Sized` by default in trait
definitions.
* Structs may contain a <abbr title="dynamically sized type">DST</abbr> as the
last field, this makes the struct itself a
<abbr title="dynamically sized type">DST</abbr>.

Notably: [variables], function parameters, [const] and [static] items must be
`Sized`.

[sized]: the-sized-trait.html
[Slices]: #array-and-slice-types
[trait objects]: #trait-objects
[Pointer types]: #pointer-types
[variables]: variables.html
[const]: items.html#constant-items
[static]: items.html#static-items
30 changes: 30 additions & 0 deletions src/interior-mutability.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Interior Mutability

Sometimes a type needs be mutated while having multiple aliases, in Rust this
is achieved using a pattern called _interior mutability_. A type has interior
mutability if its internal state can be changed through a [shared reference] to
it. This goes against the usual [requirement][ub] that the value pointed to by a
shared reference is not mutated.

[`std::cell::UnsafeCell<T>`] type is the only legal way in Rust to disable this
requirement. When `UnsafeCell<T>` is immutably aliased, it is still safe to
mutate, or obtain a mutable reference to, the `T` it contains. As with all
other types, it is undefined behavior to have multiple `&mut UnsafeCell<T>`
aliases.

Other types with interior mutability can be created by using `UnsafeCell<T>` as
a field. The standard library provides a variety of types that provide safe
interior mutability APIs. For example, [`std::cell::RefCell<T>`] uses run-time
borrow checks to ensure the usual rules around multiple references. The
[`std::sync::atomic`] module contains types that wrap a value that is only
accessed with atomic operations, allowing the value to be shared and mutated
across threads.

[shared reference]: types.hmtl#shared-references
[ub]: behavior-considered-undefined.html
[`std::mem::transmute`]: ../std/mem/fn.transmute.html
[`std::cell::UnsafeCell<T>`]: ../std/cell/struct.UnsafeCell.html
[`std::cell::RefCell<T>`]: ../std/cell/struct.RefCell.html
[`std::sync::atomic`]: ../std/sync/atomic.html


Loading

0 comments on commit ef15971

Please sign in to comment.