diff --git a/src/SUMMARY.md b/src/SUMMARY.md
index 289f59e1f2e28..1d5cd29be52b8 100644
--- a/src/SUMMARY.md
+++ b/src/SUMMARY.md
@@ -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)
diff --git a/src/dynamically-sized-types.md b/src/dynamically-sized-types.md
new file mode 100644
index 0000000000000..0933a688afc93
--- /dev/null
+++ b/src/dynamically-sized-types.md
@@ -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 DSTs. Such types can only be used in certain cases:
+
+* [Pointer types] to DSTs 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.
+* DSTs 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 DSTs. Unlike type parameters`Self: ?Sized` by default in trait
+ definitions.
+* Structs may contain a DST as the
+ last field, this makes the struct itself a
+ DST.
+
+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
diff --git a/src/interior-mutability.md b/src/interior-mutability.md
new file mode 100644
index 0000000000000..e7543ac5a273e
--- /dev/null
+++ b/src/interior-mutability.md
@@ -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`] type is the only legal way in Rust to disable this
+requirement. When `UnsafeCell` 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`
+aliases.
+
+Other types with interior mutability can be created by using `UnsafeCell` as
+a field. The standard library provides a variety of types that provide safe
+interior mutability APIs. For example, [`std::cell::RefCell`] 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`]: ../std/cell/struct.UnsafeCell.html
+[`std::cell::RefCell`]: ../std/cell/struct.RefCell.html
+[`std::sync::atomic`]: ../std/sync/atomic.html
+
+
diff --git a/src/types.md b/src/types.md
index 10d655f7c626b..900bf0d2626a7 100644
--- a/src/types.md
+++ b/src/types.md
@@ -3,21 +3,44 @@
Every variable, item and value in a Rust program has a type. The _type_ of a
*value* defines the interpretation of the memory holding it.
-Built-in types and type-constructors are tightly integrated into the language,
-in nontrivial ways that are not possible to emulate in user-defined types.
-User-defined types have limited capabilities.
+Built-in types are tightly integrated into the language, in nontrivial ways
+that are not possible to emulate in user-defined types. User-defined types have
+limited capabilities.
## Primitive types
-The primitive types are the following:
+Some types are defined by the language, rather than as part of the standard
+library, these are called _primitive types_. Some of these are induvidual
+types:
* The boolean type `bool` with values `true` and `false`.
-* The machine types (integer and floating-point).
-* The machine-dependent integer types.
-* Arrays
-* Tuples
-* Slices
-* Function pointers
+* The [machine types] (integer and floating-point).
+* The [machine-dependent integer types].
+* The [textual types] `char` and `str`.
+
+There are also some primitive constructs for generic types built in to the
+language:
+
+* [Tuples]
+* [Arrays]
+* [Slices]
+* [Function pointers]
+* [References]
+* [Pointers]
+
+[machine types]: #machine-types
+[machine-dependent integer types]: #machine-dependent-integer-types
+[textual types]: #textual-types
+[Tuples]: #tuple-types
+[Arrays]: #array-and-slice-types
+[Slices]: #array-and-slice-types
+[References]: #pointer-types
+[Pointers]: #raw-pointers
+[Function pointers]: #function-pointer-types
+[function]: #function-types
+[closure]: #closure-types
+
+## Numeric types
### Machine types
@@ -52,14 +75,14 @@ The types `char` and `str` hold textual data.
A value of type `char` is a [Unicode scalar value](
http://www.unicode.org/glossary/#unicode_scalar_value) (i.e. a code point that
-is not a surrogate) represented as a 32-bit unsigned word in the 0x0000 to
-0xD7FF or 0xE000 to 0x10FFFF range. A `[char]` array is effectively a UCS-4 /
-UTF-32 string.
+is not a surrogate), represented as a 32-bit unsigned word in the 0x0000 to
+0xD7FF or 0xE000 to 0x10FFFF range. A `[char]` is effectively a UCS-4 / UTF-32
+string.
A value of type `str` is a Unicode string, represented as an array of 8-bit
-unsigned bytes holding a sequence of UTF-8 code points. Since `str` is of
-unknown size, it is not a _first-class_ type, but can only be instantiated
-through a pointer type, such as `&str`.
+unsigned bytes holding a sequence of UTF-8 code points. Since `str` is a
+[dynamically sized type], it is not a _first-class_ type, but can only be
+instantiated through a pointer type, such as `&str`.
## Tuple types
@@ -70,8 +93,8 @@ Tuple types and values are denoted by listing the types or values of their
elements, respectively, in a parenthesized, comma-separated list.
Because tuple elements don't have a name, they can only be accessed by
-pattern-matching or by using `N` directly as a field to access the
-`N`th element.
+pattern-matching or by using `N` directly as a field to access the `N`th
+element.
An example of a tuple type and its use:
@@ -94,13 +117,18 @@ is often called ‘unit’ or ‘the unit type’.
Rust has two different types for a list of items:
* `[T; N]`, an 'array'
-* `&[T]`, a 'slice'
+* `[T]`, a 'slice'
An array has a fixed size, and can be allocated on either the stack or the
heap.
-A slice is a 'view' into an array. It doesn't own the data it points
-to, it borrows it.
+A slice is a [dynamically sized type] representing a 'view' into an array. To
+use a slice type it generally has to be used behind a pointer for example as
+
+* `&[T]`, a 'shared slice', often just called a 'slice', it doesn't own the
+ data it points to, it borrows it.
+* `&mut [T]`, a 'mutable slice', mutably borrows the data it points to.
+* `Box<[T]>`, a 'boxed slice'
Examples:
@@ -108,86 +136,104 @@ Examples:
// A stack-allocated array
let array: [i32; 3] = [1, 2, 3];
-// A heap-allocated array
-let vector: Vec = vec![1, 2, 3];
+// A heap-allocated array, coerced to a slice
+let boxed_array: Box<[i32]> = Box::new([1, 2, 3]);
-// A slice into an array
-let slice: &[i32] = &vector[..];
+// A (shared) slice into an array
+let slice: &[i32] = &boxed_array[..];
```
-As you can see, the `vec!` macro allows you to create a `Vec` easily. The
-`vec!` macro is also part of the standard library, rather than the language.
+All elements of arrays and slices are always initialized, and access to an
+array or slice is always bounds-checked in safe methods and operators.
+
+The [`Vec`] standard library type provides a heap allocated resizable array
+type.
-All in-bounds elements of arrays and slices are always initialized, and access
-to an array or slice is always bounds-checked.
+[dynamically sized type]: dynamically-sized-types.html
+[`Vec`]: ../std/vec/struct.Vec.html
## Struct types
A `struct` *type* is a heterogeneous product of other types, called the
*fields* of the type.[^structtype]
-[^structtype]: `struct` types are analogous to `struct` types in C,
- the *record* types of the ML family,
- or the *struct* types of the Lisp family.
-
New instances of a `struct` can be constructed with a [struct
expression](expressions.html#struct-expressions).
The memory layout of a `struct` is undefined by default to allow for compiler
optimizations like field reordering, but it can be fixed with the
-`#[repr(...)]` attribute. In either case, fields may be given in any order in
-a corresponding struct *expression*; the resulting `struct` value will always
+`#[repr(...)]` attribute. In either case, fields may be given in any order in a
+corresponding struct *expression*; the resulting `struct` value will always
have the same memory layout.
The fields of a `struct` may be qualified by [visibility
-modifiers](visibility-and-privacy.html), to allow access to data in a
-struct outside a module.
+modifiers](visibility-and-privacy.html), to allow access to data in a struct
+outside a module.
A _tuple struct_ type is just like a struct type, except that the fields are
anonymous.
-A _unit-like struct_ type is like a struct type, except that it has no
-fields. The one value constructed by the associated [struct
-expression](expressions.html#struct-expressions) is the only value that inhabits such a
-type.
+A _unit-like struct_ type is like a struct type, except that it has no fields.
+The one value constructed by the associated [struct
+expression](expressions.html#struct-expressions) is the only value that
+inhabits such a type.
+
+[^structtype]: `struct` types are analogous to `struct` types in C, the
+ *record* types of the ML family, or the *struct* types of the Lisp family.
## Enumerated types
An *enumerated type* is a nominal, heterogeneous disjoint union type, denoted
by the name of an [`enum` item](items.html#enumerations). [^enumtype]
+An [`enum` item](items.html#enumerations) declares both the type and a number
+of *variants*, each of which is independently named and has the syntax of a
+struct, tuple struct or unit-like struct.
+
+New instances of an `enum` can be constructed in an [enumeration variant
+expression](expressions.html#enumeration-variant-expressions).
+
+Any `enum` value consumes as much memory as the largest variant for its
+corresponding `enum` type, as well as the size needed to store a discriminant.
+
+Enum types cannot be denoted *structurally* as types, but must be denoted by
+named reference to an [`enum` item](items.html#enumerations).
+
[^enumtype]: The `enum` type is analogous to a `data` constructor declaration in
ML, or a *pick ADT* in Limbo.
-An [`enum` item](items.html#enumerations) declares both the type and a number of *variant
-constructors*, each of which is independently named and takes an optional tuple
-of arguments.
+## Union types
-New instances of an `enum` can be constructed by calling one of the variant
-constructors, in a [call expression](expressions.html#call-expressions).
+A *union type* is a nominal, heterogeneous C-like union, denoted by the name of
+a [`union` item](items.html#unions).
-Any `enum` value consumes as much memory as the largest variant constructor for
-its corresponding `enum` type.
+A union contains the value of any one of its fields. Since the accessing the
+wrong field can cause unexpected or undefined behaviour, `unsafe` is required
+to read from a union field or to write to a field that doesn't implement
+[`Copy`].
-Enum types cannot be denoted *structurally* as types, but must be denoted by
-named reference to an [`enum` item](items.html#enumerations).
+The memory layout of a `union` is undefined by default, but the `#[repr(...)]`
+attribute can be used to fix a layout.
+
+[`Copy`]: the-copy-trait.html
## Recursive types
-Nominal types — [enumerations](#enumerated-types) and
-[structs](#struct-types) — may be recursive. That is, each `enum`
-constructor or `struct` field may refer, directly or indirectly, to the
-enclosing `enum` or `struct` type itself. Such recursion has restrictions:
-
-* Recursive types must include a nominal type in the recursion
- (not mere [type definitions](../grammar.html#type-definitions),
- or other structural types such as [arrays](#array-and-slice-types) or [tuples](#tuple-types)).
-* A recursive `enum` item must have at least one non-recursive constructor
- (in order to give the recursion a basis case).
-* The size of a recursive type must be finite;
- in other words the recursive fields of the type must be [pointer types](#pointer-types).
-* Recursive type definitions can cross module boundaries, but not module *visibility* boundaries,
- or crate boundaries (in order to simplify the module system and type checker).
+Nominal types — [structs](#struct-types),
+[enumerations](#enumerated-types) and [unions](#union-types) — may be
+recursive. That is, each `enum` variant or `struct` or `union` field may refer,
+directly or indirectly, to the enclosing `enum` or `struct` type itself. Such
+recursion has restrictions:
+
+* Recursive types must include a nominal type in the recursion (not mere [type
+ definitions](../grammar.html#type-definitions), or other structural types
+ such as [arrays](#array-and-slice-types) or [tuples](#tuple-types)). So
+ `type Rec = &'static [Rec]` is not allowed.
+* The size of a recursive type must be finite; in other words the recursive
+ fields of the type must be [pointer types](#pointer-types).
+* Recursive type definitions can cross module boundaries, but not module
+ *visibility* boundaries, or crate boundaries (in order to simplify the module
+ system and type checker).
An example of a *recursive* type and its use:
@@ -202,62 +248,78 @@ let a: List = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil))));
## Pointer types
-All pointers in Rust are explicit first-class values. They can be copied,
-stored into data structs, and returned from functions. There are two
-varieties of pointer in Rust:
-
-* References (`&`)
- : These point to memory _owned by some other value_.
- A reference type is written `&type`,
- or `&'a type` when you need to specify an explicit lifetime.
- Copying a reference is a "shallow" operation:
- it involves only copying the pointer itself.
- Releasing a reference has no effect on the value it points to,
- but a reference of a temporary value will keep it alive during the scope
- of the reference itself.
-
-* Raw pointers (`*`)
- : Raw pointers are pointers without safety or liveness guarantees.
- Raw pointers are written as `*const T` or `*mut T`,
- for example `*const i32` means a raw pointer to a 32-bit integer.
- Copying or dropping a raw pointer has no effect on the lifecycle of any
- other value. Dereferencing a raw pointer or converting it to any other
- pointer type is an [`unsafe` operation](unsafe-functions.html).
- Raw pointers are generally discouraged in Rust code;
- they exist to support interoperability with foreign code,
- and writing performance-critical or low-level functions.
+All pointers in Rust are explicit first-class values. They can be moved or
+copied, stored into data structs, and returned from functions.
+
+### Shared references (`&`)
+
+These point to memory _owned by some other value_. When a shared reference to a
+value is created it prevents direct mutation of the value. [Interior
+mutability](interior-mutability.html) provides an exception for this in certain
+circumstances. As the name suggests, any number of shared references to a value
+may exit. A shared reference type is written `&type`, or `&'a type` when you
+need to specify an explicit lifetime. Copying a reference is a "shallow"
+operation: it involves only copying the pointer itself, that is, pointers are
+`Copy`. Releasing a reference has no effect on the value it points to, but
+referencing of a [temporary value](expressions.html#temporary-lifetimes) will
+keep it alive during the scope of the reference itself.
+
+### Mutable references (`&mut`)
+
+These also point to memory owned by some other value. A mutable reference type
+is written `&mut type` or `&'a mut type`. A mutable reference (that hasn't been
+borrowed) is the only way to access the value it points to, so is not `Copy`.
+
+### Raw pointers (`*const` and `*mut`)
+
+Raw pointers are pointers without safety or liveness guarantees. Raw pointers
+are written as `*const T` or `*mut T`, for example `*const i32` means a raw
+pointer to a 32-bit integer. Copying or dropping a raw pointer has no effect on
+the lifecycle of any other value. Dereferencing a raw pointer is an [`unsafe`
+operation](unsafe-functions.html), this can also be used to convert a raw
+pointer to a reference by reborrowing it (`&*` or `&mut *`). Raw pointers are
+generally discouraged in Rust code; they exist to support interoperability with
+foreign code, and writing performance-critical or low-level functions.
+
+When comparing pointers they are compared by their address, rather than by what
+they point to. When comparing pointers to [dynamically sized
+types](dynamically-sized-types.html) they also have their addition data
+compared.
+
+### Smart Pointers
The standard library contains additional 'smart pointer' types beyond references
and raw pointers.
## Function item types
-When referred to, a function item yields a zero-sized value of its
-_function item type_. That type explicitly identifies the function - its name,
-its type arguments, and its early-bound lifetime arguments (but not its
-late-bound lifetime arguments, which are only assigned when the function
-is called) - so the value does not need to contain an actual function pointer,
-and no indirection is needed when the function is called.
+When referred to, a function item, or the constructor of a tuple-like struct or
+enum variant, yields a zero-sized value of its _function item type_. That type
+explicitly identifies the function - its name, its type arguments, and its
+early-bound lifetime arguments (but not its late-bound lifetime arguments,
+which are only assigned when the function is called) - so the value does not
+need to contain an actual function pointer, and no indirection is needed when
+the function is called.
There is currently no syntax that directly refers to a function item type, but
-the compiler will display the type as something like `fn() {foo::}` in error
-messages.
+the compiler will display the type as something like `fn() {foo::}` in
+error messages.
Because the function item type explicitly identifies the function, the item
types of different functions - different items, or the same item with different
generics - are distinct, and mixing them will create a type error:
-```rust,ignore
+```rust,compile_fail,E0308
fn foo() { }
let x = &mut foo::;
*x = foo::; //~ ERROR mismatched types
```
-However, there is a [coercion] from function items to [function pointers](#function-pointer-types)
-with the same signature, which is triggered not only when a function item
-is used when a function pointer is directly expected, but also when different
-function item types with the same signature meet in different arms of the same
-`if` or `match`:
+However, there is a [coercion] from function items to [function
+pointers](#function-pointer-types) with the same signature, which is triggered
+not only when a function item is used when a function pointer is directly
+expected, but also when different function item types with the same signature
+meet in different arms of the same `if` or `match`:
[coercion]: type-coercions.html
@@ -278,16 +340,16 @@ let foo_ptr_2 = if want_i32 {
## Function pointer types
-Function pointer types, created using the `fn` type constructor, refer
-to a function whose identity is not necessarily known at compile-time. They
-can be created via a coercion from both [function items](#function-item-types)
-and non-capturing [closures](#closure-types).
+Function pointer types, written using the `fn` keyword, refer to a function
+whose identity is not necessarily known at compile-time. They can be created
+via a coercion from both [function items](#function-item-types) and
+non-capturing [closures](#closure-types).
A function pointer type consists of a possibly-empty set of function-type
modifiers (such as `unsafe` or `extern`), a sequence of input types and an
output type.
-An example of a `fn` type:
+An example where `Binop` is defined as a function pointer type:
```rust
fn add(x: i32, y: i32) -> i32 {
@@ -310,23 +372,24 @@ Depending on the requirements of the closure, its type implements one or
more of the closure traits:
* `FnOnce`
- : The closure can be called once. A closure called as `FnOnce`
- can move out values from its environment.
+ : The closure can be called once. A closure called as `FnOnce` can move out
+ of its captured values.
* `FnMut`
: The closure can be called multiple times as mutable. A closure called as
`FnMut` can mutate values from its environment. `FnMut` inherits from
`FnOnce` (i.e. anything implementing `FnMut` also implements `FnOnce`).
-* `Fn`
- : The closure can be called multiple times through a shared reference.
- A closure called as `Fn` can neither move out from nor mutate values
- from its environment, but read-only access to such values is allowed.
- `Fn` inherits from `FnMut`, which itself inherits from `FnOnce`.
+* `Fn` : The closure can be called multiple times through a shared reference. A
+ closure called as `Fn` can neither move out from nor mutate captured
+ variables, but read-only access to such values is allowed. Using `move` to
+ capture variables by value is allowed so long as they aren't mutated or
+ moved in the body of the closure. `Fn` inherits from `FnMut`, which itself
+ inherits from `FnOnce`.
-Closures that don't use anything from their environment ("non capturing closures")
-can be coerced to function pointers (`fn`) with the matching signature.
-To adopt the example from the section above:
+Closures that don't use anything from their environment ("non capturing
+closures") can be coerced to function pointers (`fn`) with the matching
+signature. To adopt the example from the section above:
```rust
let add = |x, y| x + y;
@@ -340,8 +403,12 @@ x = bo(5,7);
## Trait objects
-In Rust, a type like `&SomeTrait` or `Box` is called a _trait object_.
-Each instance of a trait object includes:
+In Rust, trait names also refer to [dynamically sized types] called _trait
+objects_. Like all DSTs, trait
+objects are used behind some kind of pointer: `&SomeTrait` or `Box`.
+Each instance of a pointer to a trait object includes:
+
+[dynamically sized types]: dynamically-sized-types.html
- a pointer to an instance of a type `T` that implements `SomeTrait`
- a _virtual method table_, often just called a _vtable_, which contains, for
@@ -354,11 +421,18 @@ function pointer is loaded from the trait object vtable and invoked indirectly.
The actual implementation for each vtable entry can vary on an object-by-object
basis.
-Note that for a trait object to be instantiated, the trait must be
-_object-safe_. Object safety rules are defined in [RFC 255].
+Note that trait object types only exist for _object-safe_ traits ([RFC 255]):
[RFC 255]: https://github.com/rust-lang/rfcs/blob/master/text/0255-object-safety.md
+* It must not require `Self: Sized`
+* All associated functions must either have a `where Self: Sized` bound or
+ * Not have any type parameters (lifetime parameters are allowed)
+ * Must be a method: its first parameter must be called self, with type
+ `Self`, `&Self`, `&mut Self`, `Box`.
+ * `Self` may only be used in the type of the receiver.
+* It must not have any associated constants.
+
Given a pointer-typed expression `E` of type `&T` or `Box`, where `T`
implements trait `R`, casting `E` to the corresponding pointer type `&R` or
`Box` results in a value of the _trait object_ `R`. This result is
@@ -396,28 +470,45 @@ These were defined in [RFC 599] and amended in [RFC 1156].
[RFC 599]: https://github.com/rust-lang/rfcs/blob/master/text/0599-default-object-bound.md
[RFC 1156]: https://github.com/rust-lang/rfcs/blob/master/text/1156-adjust-default-object-bounds.md
-For traits that themselves have no lifetime parameters, the default bound is
-based on what kind of trait object is used:
+For traits that themselves have no lifetime parameters:
+* If there is a unique bound from the containing type then that is the default
+* If there is more than one bound from the containing type then an explicit bound must
+ be specified
+* Otherwise the default bound is `'static`
```rust,ignore
// For the following trait...
trait Foo { }
-// ...these two are the same:
+// These two are the same as Box has no lifetime bound on T
Box
Box
// ...and so are these:
+impl Foo {}
+impl Foo + 'static {}
+
+// ...so are these, because &'a T requires T: 'a
&'a Foo
&'a (Foo + 'a)
+
+// std::cell::Ref<'a, T> also requires T: 'a, so these are the same
+std::cell::Ref<'a, Foo>
+std::cell::Ref<'a, Foo + 'a>
+
+// This is an error:
+struct TwoBounds<'a, 'b, T: ?Sized + 'a + 'b>
+TwoBounds<'a, 'b, Foo> // Error: the lifetime bound for this object type cannot
+ // be deduced from context
+
```
The `+ 'static` and `+ 'a` refer to the default bounds of those kinds of trait
objects, and also to how you can directly override them. Note that the innermost
object sets the bound, so `&'a Box` is still `&'a Box`.
-For traits that have lifetime parameters of their own, the default bound is
-based on that lifetime parameter:
+For traits that have a single lifetime _bound_ of their own then, instead of
+infering 'static as the default bound, the bound on the trait is used instead
```rust,ignore
// For the following trait...
@@ -426,15 +517,17 @@ trait Bar<'a>: 'a { }
// ...these two are the same:
Box>
Box + 'a>
-```
-The default for user-defined trait objects is based on the object type itself.
-If a type parameter has a lifetime bound, then that lifetime bound becomes the
-default bound for trait objects of that type. For example, `std::cell::Ref<'a,
-T>` contains a `T: 'a` bound, therefore trait objects of type `Ref<'a,
-SomeTrait>` are the same as `Ref<'a, (SomeTrait + 'a)>`.
+// ...and so are these:
+impl<'a> Foo<'a> {}
+impl<'a> Foo<'a> + 'a {}
+
+// This is still an error:
+struct TwoBounds<'a, 'b, T: ?Sized + 'a + 'b>
+TwoBounds<'a, 'b, Foo<'c>>
+```
-### Type parameters
+## Type parameters
Within the body of an item that has type parameter declarations, the names of
its type parameters are types:
@@ -451,14 +544,13 @@ fn to_vec(xs: &[A]) -> Vec {
}
```
-Here, `first` has type `A`, referring to `to_vec`'s `A` type parameter; and `rest`
-has type `Vec`, a vector with element type `A`.
+Here, `first` has type `A`, referring to `to_vec`'s `A` type parameter; and
+`rest` has type `Vec`, a vector with element type `A`.
## Self types
-The special type `Self` has a meaning within traits and impls. In a trait definition, it refers
-to an implicit type parameter representing the "implementing" type. In an impl,
-it is an alias for the implementing type. For example, in:
+The special type `Self` has a meaning within traits and impls: it refers to
+the implementing type. For example, in:
```rust
pub trait From {
@@ -472,8 +564,8 @@ impl From for String {
}
```
-The notation `Self` in the impl refers to the implementing type: `String`. In another
-example:
+The notation `Self` in the impl refers to the implementing type: `String`. In
+another example:
```rust
trait Printable {
@@ -487,6 +579,4 @@ impl Printable for String {
}
```
-The notation `&self` is a shorthand for `self: &Self`. In this case,
-in the impl, `Self` refers to the value of type `String` that is the
-receiver for a call to the method `make_string`.
+The notation `&self` is a shorthand for `self: &Self`.
\ No newline at end of file