From a68b9e546a91c30d19c3d4e463ccd0e5723f1ff6 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 9 Dec 2017 17:54:48 +0000 Subject: [PATCH] Rewrite the special traits section --- src/SUMMARY.md | 8 +- src/dynamically-sized-types.md | 2 +- src/expressions.md | 14 +-- src/expressions/array-expr.md | 2 +- src/expressions/closure-expr.md | 7 +- src/expressions/field-expr.md | 6 +- src/items/constant-items.md | 8 +- src/special-traits.md | 3 - src/special-types-and-traits.md | 154 ++++++++++++++++++++++++++++++++ src/the-copy-trait.md | 4 - src/the-deref-trait.md | 7 -- src/the-drop-trait.md | 4 - src/the-send-trait.md | 4 - src/the-sized-trait.md | 3 - src/the-sync-trait.md | 4 - src/types.md | 2 +- src/unsafety.md | 2 +- 17 files changed, 178 insertions(+), 56 deletions(-) delete mode 100644 src/special-traits.md create mode 100644 src/special-types-and-traits.md delete mode 100644 src/the-copy-trait.md delete mode 100644 src/the-deref-trait.md delete mode 100644 src/the-drop-trait.md delete mode 100644 src/the-send-trait.md delete mode 100644 src/the-sized-trait.md delete mode 100644 src/the-sync-trait.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 5464df575..642e4b483 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -67,13 +67,7 @@ - [Type coercions](type-coercions.md) - [Destructors](destructors.md) -- [Special traits](special-traits.md) - - [The Copy trait](the-copy-trait.md) - - [The Sized trait](the-sized-trait.md) - - [The Drop trait](the-drop-trait.md) - - [The Deref trait](the-deref-trait.md) - - [The Send trait](the-send-trait.md) - - [The Sync trait](the-sync-trait.md) +- [Special types and traits](special-types-and-traits.md) - [Memory model](memory-model.md) - [Memory allocation and lifetime](memory-allocation-and-lifetime.md) diff --git a/src/dynamically-sized-types.md b/src/dynamically-sized-types.md index 5485ef7a0..4293ddd5a 100644 --- a/src/dynamically-sized-types.md +++ b/src/dynamically-sized-types.md @@ -23,7 +23,7 @@ types">DSTs. Such types can only be used in certain cases: Notably: [variables], function parameters, [const] and [static] items must be `Sized`. -[sized]: the-sized-trait.html +[sized]: special-types-and-traits.html#sized [Slices]: types.html#array-and-slice-types [trait objects]: types.html#trait-objects [Pointer types]: types.html#pointer-types diff --git a/src/expressions.md b/src/expressions.md index e5166cffb..8de000937 100644 --- a/src/expressions.md +++ b/src/expressions.md @@ -44,7 +44,7 @@ evaluated in the order given by their associativity. | `=` `+=` `-=` `*=` `/=` `%=`
`&=` |= `^=` `<<=` `>>=` | right to left | | `return` `break` closures | | -## Place Expressions and Value Expressions +## Place Expressions and Value Expressions Expressions are divided into two main categories: place expressions and value expressions. Likewise within each expression, sub-expressions may occur @@ -72,15 +72,14 @@ expression context. All other expression contexts are value expression contexts. When a place expression is evaluated in a value expression context, or is bound by value in a pattern, it denotes the value held _in_ that memory location. If -the type of that value implements `Copy`, then the value will be copied. In the -remaining situations if that type is [`Sized`](the-sized-trait.html), then it -may be possible to move the value. Only the following place expressions may be -moved out of: +the type of that value implements [`Copy`], then the value will be copied. In +the remaining situations if that type is [`Sized`], then it may be possible to +move the value. Only the following place expressions may be moved out of: * [Variables] which are not currently borrowed. * [Temporary values](#temporary-lifetimes). * [Fields][field] of a place expression which can be moved out of and - doesn't implement [`Drop`](the-drop-trait.html). + doesn't implement [`Drop`]. * The result of [dereferencing] an expression with type [`Box`] and that can also be moved out of. @@ -281,6 +280,9 @@ exist in `core::ops` and `core::cmp` with the same names. [destructors]: destructors.html [interior mutability]: interior-mutability.html [`Box`]: ../std/boxed/struct.Box.html +[`Copy`]: special-types-and-traits.html#copy +[`Drop`]: special-types-and-traits.html#drop +[`Sized`]: special-types-and-traits.html#sized [implicit borrow]: #implicit-borrows [implicitly mutably borrowed]: #implicit-borrows [let]: statements.html#let-statements diff --git a/src/expressions/array-expr.md b/src/expressions/array-expr.md index 132e45333..c437d8c27 100644 --- a/src/expressions/array-expr.md +++ b/src/expressions/array-expr.md @@ -20,7 +20,7 @@ such as a [literal](tokens.html#literals) or a [constant item](items/constant-items.html). `[a; b]` creates an array containing `b` copies of the value of `a`. If the expression after the semi-colon has a value greater than 1 then this requires that the type of `a` is -[`Copy`](the-copy-trait.html). +[`Copy`](special-types-and-traits.html#copy). ```rust [1, 2, 3, 4]; diff --git a/src/expressions/closure-expr.md b/src/expressions/closure-expr.md index 36817f804..da20ded06 100644 --- a/src/expressions/closure-expr.md +++ b/src/expressions/closure-expr.md @@ -37,9 +37,10 @@ closure's type is `'static`. The compiler will determine which of the [closure traits](types.html#closure-types) the closure's type will implement by how it acts on its captured variables. The closure will also implement -[`Send`](the-send-trait.html) and/or [`Sync`](the-sync-trait.html) if all of -its captured types do. These traits allow functions to accept closures using -generics, even though the exact types can't be named. +[`Send`](special-types-and-traits.html#send) and/or +[`Sync`](special-types-and-traits.html#sync) if all of its captured types do. +These traits allow functions to accept closures using generics, even though the +exact types can't be named. In this example, we define a function `ten_times` that takes a higher-order function argument, and we then call it with a closure expression as an argument, diff --git a/src/expressions/field-expr.md b/src/expressions/field-expr.md index 8cc873dd3..ebbdbe24f 100644 --- a/src/expressions/field-expr.md +++ b/src/expressions/field-expr.md @@ -27,9 +27,9 @@ possible. In cases of ambiguity, we prefer fewer autoderefs to more. Finally, the fields of a struct or a reference to a struct are treated as separate entities when borrowing. If the struct does not implement -[`Drop`](the-drop-trait.html) and is stored in a local variable, this also -applies to moving out of each of its fields. This also does not apply if -automatic dereferencing is done though user defined types. +[`Drop`](special-types-and-traits.html#drop) and is stored in a local variable, +this also applies to moving out of each of its fields. This also does not apply +if automatic dereferencing is done though user defined types. ```rust struct A { f1: String, f2: String, f3: String } diff --git a/src/items/constant-items.md b/src/items/constant-items.md index e395cb215..0800aa106 100644 --- a/src/items/constant-items.md +++ b/src/items/constant-items.md @@ -1,8 +1,8 @@ # Constant items -> **Syntax** -> _ConstantItem_ : ->    `const` [IDENTIFIER] `:` [_Type_] `=` [_Expression_] `;` +> **Syntax** +> _ConstantItem_ : +>    `const` [IDENTIFIER] `:` [_Type_] `=` [_Expression_] `;` A *constant item* is a named _[constant value]_ which is not associated with a specific memory location in the program. Constants are essentially inlined @@ -62,7 +62,7 @@ fn create_and_drop_zero_with_destructor() { [constant value]: expressions.html#constant-expressions [static lifetime elision]: items/static-items.html#static-lifetime-elision -[`Drop`]: the-drop-trait.html +[`Drop`]: special-types-and-traits.html#drop [IDENTIFIER]: identifiers.html [_Type_]: types.html [_Expression_]: expressions.html diff --git a/src/special-traits.md b/src/special-traits.md deleted file mode 100644 index ae3eebe39..000000000 --- a/src/special-traits.md +++ /dev/null @@ -1,3 +0,0 @@ -# Special traits - -Several traits define special evaluation behavior. diff --git a/src/special-types-and-traits.md b/src/special-types-and-traits.md new file mode 100644 index 000000000..59b74ccb1 --- /dev/null +++ b/src/special-types-and-traits.md @@ -0,0 +1,154 @@ +# Special types and traits + +Certain types and traits that exist in [the standard library] are known to the +Rust compiler. This chapter documents the special features of these types and +traits. + +## `Box` + +[`Box`] has a few special features that Rust doesn't currently allow for user +defined types. + +* The [dereference operator] for `Box` produces a place which can be moved + from. This means that the `*` operator and the destructor of `Box` are + built-in to the language. +* [Methods] can take `Box` as a receiver. +* A trait may be implemented for `Box` in the same crate as `T`, which the + [orphan rules] prevent for other generic types. + +## `UnsafeCell` + +[`std::cell::UnsafeCell`] is used for [interior mutability]. It ensures that +the compiler doesn't perform optimisations that are incorrect for such types. +It also ensures that [`static` items] which have a type with interior +mutability aren't placed in memory marked as read only. + +## `PhantomData` + +[`std::marker::PhantomData`] is a zero-sized, minimum alignment, type that +is considered to own a `T` for the purposes of [variance], [drop check] and +[auto traits](#auto-traits). + +## Operator Traits + +The traits in [`std::ops`] and [`std::cmp`] are used to overload [operators], +[indexing expressions] and [call expressions]. + +## `Deref` and `DerefMut` + +As well as overloading the unary `*` operator, [`Deref`] and [`DerefMut`] are +also used in [method resolution] and [deref coercions]. + +## `Drop` + +The [`Drop`] trait provides a [destructor], to be run whenever a value of this +type is to be destroyed. + +## `Copy` + +The [`Copy`] trait changes the semantics of a type implementing it. Values +whose type implements `Copy` are copied rather than moved upon assignment. +`Copy` cannot be implemented for types which implement `Drop`, or which have +fields that are not `Copy`. `Copy` is implemented by the compiler for + +* [Numeric types] +* `char` and `bool` +* [Tuples] of `Copy` types +* [Arrays] of `Copy` types +* [Shared references] +* [Raw pointers] +* [Function pointers] and [function item types] + +## `Clone` + +The [`Clone`] trait is a supertrait of `Copy`, so it also needs compiler +generated implementations. It is implemented by the compiler for the following +types: + +* Types with a built-in `Copy` implementation (see above) +* [Tuples] of `Clone` types +* [Arrays] of `Clone` types + +## `Send` + +The [`Send`] trait indicates that a value of this type is safe to send from one +thread to another. + +## `Sync` + +The [`Sync`] trait indicates that a value of this type is safe to share between +multiple threads. This trait must be implemented for all types used in +immutable [`static` items]. + +## Auto traits + +The [`Send`], [`Sync`], [`UnwindSafe`] and [`RefUnwindSafe`] traits are _auto +traits_. Auto traits have special properties. + +First, auto traits are automatically implemented using the following rules: + +* `&T`, `&mut T`, `*const T`, `*mut T`, `[T; n]` and `[T]` implement the trait + if `T` does. +* Function item types and function pointers automatically implement the trait. +* Structs, enums, unions and tuples implement the trait if all of their fields + do. +* Closures implement the trait if the types of all of their captures do. A + closure that captures a `T` by shared reference and a `U` by value implements + any auto traits that both `&T` and `U` do. + +Auto traits can also have negative implementations, shown as `impl !AutoTrait +for T` in the standard library documentation, that override the automatic +implementations. For example `*mut T` has a negative implementation of `Send`, +and so `*mut T` and `(*mut T,)` are not `Send`. Finally, auto traits may +be added as a bound to any [trait object]\: `Box` is +a valid type. + +## `Sized` + +The [`Sized`] trait indicates that the size of this type is known at +compile-time; that is, it's not a [dynamically sized type]. [Type parameters] +are `Sized` by default. `Sized` is always implemented automatically by the +compiler, not by [implementation items]. + +[`Box`]: ../std/boxed/struct.Box.html +[`Clone`]: ../std/clone/trait.Clone.html +[`Copy`]: ../std/marker/trait.Copy.html +[`Deref`]: ../std/ops/trait.Deref.html +[`DerefMut`]: ../std/ops/trait.DerefMut.html +[`Drop`]: ../std/ops/trait.Drop.html +[`RefUnwindSafe`]: ../std/panic/trait.RefUnwindSafe.html +[`Send`]: ../std/marker/trait.Send.html +[`Sized`]: ../std/marker/trait.Sized.html +[`std::cell::UnsafeCell`]: ../std/cell/struct.UnsafeCell.html +[`std::cmp`]: ../std/cmp/index.html +[`std::marker::PhantomData`]: ../std/marker/struct.PhantomData.html +[`std::ops`]: ../std/ops/index.html +[`UnwindSafe`]: ../std/panic/trait.UnwindSafe.html +[`Sync`]: ../std/marker/trait.Sync.html + +[Arrays]: types.html#array-and-slice-types +[call expressions]: expressoins/call-expr.html +[deref coercions]: type-coercions.html#coercion-types +[dereference operator]: expressions/operator-expr.html#the-dereference-operator +[destructor]: destructors.html +[drop check]: ../nomicon/dropck.html +[dynamically sized type]: dynamically-sized-types.html +[Function pointers]: types.html#function-pointer-types +[function item types]: types.html#function-item-types +[implementation items]: items.html/implementations.html +[indexing expressions]: expressions/array-expr.html#array-and-slice-indexing-expressions +[interior mutability]: iterior-mutability.html +[lang items]: attributes.html#language-items +[Numeric types]: types.html#numeric-types +[Methods]: items.html#associated-functions-and-methods +[method resolution]: expressions/method-call-expr.html +[operators]: expressions/operator-expr.html +[orphan rules]: items/implementations.html#trait-implementation-coherence +[Raw pointers]: types.html#raw-pointers-const-and-mut +[`static` items]: items/static-items.html +[Shared references]: types.html#shared-references- +[the standard library]: ../std/index.html +[trait object]: types.html#trait-objects +[Tuples]: types.html#tuple-types +[Type parameters]: types.html#type-parameters +[variance]: ../nomicon/subtyping.html diff --git a/src/the-copy-trait.md b/src/the-copy-trait.md deleted file mode 100644 index d593165e4..000000000 --- a/src/the-copy-trait.md +++ /dev/null @@ -1,4 +0,0 @@ -# The `Copy` trait - -The `Copy` trait changes the semantics of a type implementing it. Values whose -type implements `Copy` are copied rather than moved upon assignment. diff --git a/src/the-deref-trait.md b/src/the-deref-trait.md deleted file mode 100644 index a4d84ab83..000000000 --- a/src/the-deref-trait.md +++ /dev/null @@ -1,7 +0,0 @@ -# The `Deref` trait - -The `Deref` trait allows a type to implicitly implement all the methods -of the type `U`. When attempting to resolve a method call, the compiler will search -the top-level type for the implementation of the called method. If no such method is -found, `.deref()` is called and the compiler continues to search for the method -implementation in the returned type `U`. diff --git a/src/the-drop-trait.md b/src/the-drop-trait.md deleted file mode 100644 index 42bf6eb0f..000000000 --- a/src/the-drop-trait.md +++ /dev/null @@ -1,4 +0,0 @@ -# The `Drop` trait - -The `Drop` trait provides a destructor, to be run whenever a value of this type -is to be destroyed. diff --git a/src/the-send-trait.md b/src/the-send-trait.md deleted file mode 100644 index 9ec669289..000000000 --- a/src/the-send-trait.md +++ /dev/null @@ -1,4 +0,0 @@ -# The `Send` trait - -The `Send` trait indicates that a value of this type is safe to send from one -thread to another. diff --git a/src/the-sized-trait.md b/src/the-sized-trait.md deleted file mode 100644 index a2aa17c95..000000000 --- a/src/the-sized-trait.md +++ /dev/null @@ -1,3 +0,0 @@ -# The `Sized` trait - -The `Sized` trait indicates that the size of this type is known at compile-time. diff --git a/src/the-sync-trait.md b/src/the-sync-trait.md deleted file mode 100644 index fd9365134..000000000 --- a/src/the-sync-trait.md +++ /dev/null @@ -1,4 +0,0 @@ -# The `Sync` trait - -The `Sync` trait indicates that a value of this type is safe to share between -multiple threads. diff --git a/src/types.md b/src/types.md index 553a14247..c6bb1491e 100644 --- a/src/types.md +++ b/src/types.md @@ -215,7 +215,7 @@ to read from a union field or to write to a field that doesn't implement 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 +[`Copy`]: special-types-and-traits.html#copy ## Recursive types diff --git a/src/unsafety.md b/src/unsafety.md index a68353aed..452215d8d 100644 --- a/src/unsafety.md +++ b/src/unsafety.md @@ -9,6 +9,6 @@ Rust: - Dereferencing a [raw pointer](types.html#pointer-types). - Reading or writing a [mutable static variable](items/static-items.html#mutable-statics). - Reading a field of a [`union`](items/unions.html), or writing to a field of a - union that isn't [`Copy`](the-copy-trait.html). + union that isn't [`Copy`](special-types-and-traits.html#copy). - Calling an unsafe function (including an intrinsic or foreign function). - Implementing an unsafe trait.