From 0a15f29adb9988fcf4a57754c820332f5b3b214a Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 16 Oct 2018 18:52:31 -0700 Subject: [PATCH 1/3] Split Types Chapter This splits the types chapter into multiple subchapters. I tried to avoid content changes, but I ended up with a few changes: - Added overview links in `types.md`, and a separate discussion of type expressions. - Split array and slice into separate chapters. Although there is some overlap between them, I feel like it was awkward explaining one and then the other. I also felt it conflated the two too much since slices can be used for more than arrays. - Combined `Self` section with the one on the paths page. - Added a basic redirector for external links. Some pages may seem a little bare now, but I think each type page has potential to be expanded and improved in the future. --- src/SUMMARY.md | 16 + src/const_eval.md | 4 +- src/destructors.md | 12 +- src/dynamically-sized-types.md | 6 +- src/expressions.md | 2 +- src/expressions/array-expr.md | 4 +- src/expressions/call-expr.md | 2 +- src/expressions/closure-expr.md | 6 +- src/expressions/loop-expr.md | 2 +- src/expressions/method-call-expr.md | 6 +- src/expressions/operator-expr.md | 8 +- src/expressions/tuple-expr.md | 4 +- src/glossary.md | 2 +- src/interior-mutability.md | 2 +- src/items/associated-items.md | 8 +- src/items/constant-items.md | 2 +- src/items/enumerations.md | 2 +- src/items/external-blocks.md | 2 +- src/items/functions.md | 6 +- src/items/generics.md | 14 +- src/items/implementations.md | 2 +- src/items/static-items.md | 2 +- src/items/structs.md | 6 +- src/items/traits.md | 4 +- src/items/type-aliases.md | 2 +- src/keywords.md | 2 +- src/lifetime-elision.md | 8 +- src/macros-by-example.md | 2 +- src/paths.md | 20 +- src/patterns.md | 2 +- src/special-types-and-traits.md | 18 +- src/subtyping.md | 6 +- src/tokens.md | 12 +- src/trait-bounds.md | 2 +- src/types-redirect.html | 41 ++ src/types.md | 943 ++++------------------------ src/types/array.md | 32 + src/types/boolean.md | 17 + src/types/closure.md | 177 ++++++ src/types/enum.md | 23 + src/types/function-item.md | 57 ++ src/types/function-pointer.md | 55 ++ src/types/impl-trait.md | 37 ++ src/types/never.md | 8 + src/types/numeric.md | 28 + src/types/pointer.md | 57 ++ src/types/slice.md | 32 + src/types/struct.md | 28 + src/types/textual.md | 16 + src/types/trait-object.md | 114 ++++ src/types/tuple.md | 34 + src/types/union.md | 15 + src/unsafety.md | 2 +- 53 files changed, 1010 insertions(+), 904 deletions(-) create mode 100644 src/types-redirect.html create mode 100644 src/types/array.md create mode 100644 src/types/boolean.md create mode 100644 src/types/closure.md create mode 100644 src/types/enum.md create mode 100644 src/types/function-item.md create mode 100644 src/types/function-pointer.md create mode 100644 src/types/impl-trait.md create mode 100644 src/types/never.md create mode 100644 src/types/numeric.md create mode 100644 src/types/pointer.md create mode 100644 src/types/slice.md create mode 100644 src/types/struct.md create mode 100644 src/types/textual.md create mode 100644 src/types/trait-object.md create mode 100644 src/types/tuple.md create mode 100644 src/types/union.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 6259cfac9..2022cbf06 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -67,6 +67,22 @@ - [Type system](type-system.md) - [Types](types.md) + - [Boolean type](types/boolean.md) + - [Numeric types](types/numeric.md) + - [Textual types](types/textual.md) + - [Never type](types/never.md) + - [Tuple types](types/tuple.md) + - [Array types](types/array.md) + - [Slice types](types/slice.md) + - [Struct types](types/struct.md) + - [Enumerated types](types/enum.md) + - [Union types](types/union.md) + - [Function item types](types/function-item.md) + - [Closure types](types/closure.md) + - [Pointer types](types/pointer.md) + - [Function pointer types](types/function-pointer.md) + - [Trait object types](types/trait-object.md) + - [Impl trait type](types/impl-trait.md) - [Dynamically Sized Types](dynamically-sized-types.md) - [Type layout](type-layout.md) - [Interior mutability](interior-mutability.md) diff --git a/src/const_eval.md b/src/const_eval.md index 264d4beec..b4b28d5af 100644 --- a/src/const_eval.md +++ b/src/const_eval.md @@ -51,7 +51,7 @@ A _const context_ is one of the following: * [statics] * [enum discriminants] -[array type length expressions]: types.html#array-and-slice-types +[array type length expressions]: types/array.html [enum discriminants]: items/enumerations.html#custom-discriminant-values-for-field-less-enumerations [constants]: items/constant-items.html [statics]: items/static-items.html @@ -68,7 +68,7 @@ A _const context_ is one of the following: [block expressions]: expressions/block-expr.html [field]: expressions/field-expr.html [array indexing]: expressions/array-expr.html#array-and-slice-indexing-expressions -[slice]: types.html#array-and-slice-types +[slice]: types/slice.html [range expressions]: expressions/range-expr.html [closure expressions]: expressions/closure-expr.html [negation]: expressions/operator-expr.html#negation-operators diff --git a/src/destructors.md b/src/destructors.md index 263480ed3..1f0055f94 100644 --- a/src/destructors.md +++ b/src/destructors.md @@ -82,12 +82,12 @@ variable or field from being dropped automatically. [Assignment]: expressions/operator-expr.html#assignment-expressions [`std::ops::Drop::drop`]: ../std/ops/trait.Drop.html [RFC 1857]: https://github.com/rust-lang/rfcs/blob/master/text/1857-stabilize-drop-order.md -[struct]: types.html#struct-types -[tuple]: types.html#tuple-types -[enum variant]: types.html#enumerated-types -[array]: types.html#array-and-slice-types -[closure]: types.html#closure-types -[Trait objects]: types.html#trait-objects +[struct]: types/struct.html +[tuple]: types/tuple.html +[enum variant]: types/enum.html +[array]: types/array.html +[closure]: types/closure.html +[Trait objects]: types/trait-object.html [`std::ptr::drop_in_place`]: ../std/ptr/fn.drop_in_place.html [`std::mem::forget`]: ../std/mem/fn.forget.html [`std::mem::ManuallyDrop`]: ../std/mem/struct.ManuallyDrop.html diff --git a/src/dynamically-sized-types.md b/src/dynamically-sized-types.md index 6cc3911da..7fd25ab30 100644 --- a/src/dynamically-sized-types.md +++ b/src/dynamically-sized-types.md @@ -24,9 +24,9 @@ Notably: [variables], function parameters, [const] and [static] items must be `Sized`. [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 +[Slices]: types/slice.html +[trait objects]: types/trait-object.html +[Pointer types]: types/pointer.html [variables]: variables.html [const]: items/constant-items.html [static]: items/static-items.html diff --git a/src/expressions.md b/src/expressions.md index fc6104a44..c098e6d96 100644 --- a/src/expressions.md +++ b/src/expressions.md @@ -316,7 +316,7 @@ They are never allowed before: [let statement]: statements.html#let-statements [Mutable `static` items]: items/static-items.html#mutable-statics [const contexts]: const_eval.html -[slice]: types.html#array-and-slice-types +[slice]: types/slice.html [statement]: statements.html [static variables]: items/static-items.html [Temporary values]: #temporary-lifetimes diff --git a/src/expressions/array-expr.md b/src/expressions/array-expr.md index 6558e6013..7506934dd 100644 --- a/src/expressions/array-expr.md +++ b/src/expressions/array-expr.md @@ -10,7 +10,7 @@ >       [_Expression_] ( `,` [_Expression_] )\* `,`?\ >    | [_Expression_] `;` [_Expression_] -An _[array](types.html#array-and-slice-types) expression_ can be written by +An _[array](types/array.html) expression_ can be written by enclosing zero or more comma-separated expressions of uniform type in square brackets. This produces and array containing each of these values in the order they are written. @@ -44,7 +44,7 @@ expressions]. > _IndexExpression_ :\ >    [_Expression_] `[` [_Expression_] `]` -[Array and slice](types.html#array-and-slice-types)-typed expressions can be +[Array](types/array.html) and [slice](types/slice.html)-typed expressions can be indexed by writing a square-bracket-enclosed expression of type `usize` (the index) after them. When the array is mutable, the resulting [memory location] can be assigned to. diff --git a/src/expressions/call-expr.md b/src/expressions/call-expr.md index 8193b091f..9f3414a45 100644 --- a/src/expressions/call-expr.md +++ b/src/expressions/call-expr.md @@ -10,7 +10,7 @@ A _call expression_ consists of an expression followed by a parenthesized expression-list. It invokes a function, providing zero or more input variables. If the function eventually returns, then the expression completes. For -[non-function types](types.html#function-item-types), the expression f(...) uses +[non-function types](types/function-item.html), the expression f(...) uses the method on one of the [`std::ops::Fn`], [`std::ops::FnMut`] or [`std::ops::FnOnce`] traits, which differ in whether they take the type by reference, mutable reference, or take ownership respectively. An automatic diff --git a/src/expressions/closure-expr.md b/src/expressions/closure-expr.md index 7cc3a7dda..e10775d00 100644 --- a/src/expressions/closure-expr.md +++ b/src/expressions/closure-expr.md @@ -25,7 +25,7 @@ functions, as an abbreviation for defining and capturing a separate function. Significantly, closure expressions _capture their environment_, which regular [function definitions] do not. Without the `move` keyword, the closure expression -[infers how it captures each variable from its environment](types.html#capture-modes), +[infers how it captures each variable from its environment](types/closure.html#capture-modes), preferring to capture by shared reference, effectively borrowing all outer variables mentioned inside the closure's body. If needed the compiler will infer that instead mutable references should be taken, or that the values @@ -35,7 +35,7 @@ prefixing it with the `move` keyword. This is often used to ensure that the closure's type is `'static`. The compiler will determine which of the [closure -traits](types.html#call-traits-and-coercions) the closure's type will implement by how it +traits](types/closure.html#call-traits-and-coercions) the closure's type will implement by how it acts on its captured variables. The closure will also implement [`Send`](special-types-and-traits.html#send) and/or [`Sync`](special-types-and-traits.html#sync) if all of its captured types do. @@ -67,5 +67,5 @@ ten_times(move |j| println!("{}, {}", word, j)); [_Expression_]: expressions.html [_BlockExpression_]: expressions/block-expr.html -[_TypeNoBounds_]: types.html +[_TypeNoBounds_]: types.html#type-expressions [_FunctionParameters_]: items/functions.html diff --git a/src/expressions/loop-expr.md b/src/expressions/loop-expr.md index 24a8f1b4b..1098f262c 100644 --- a/src/expressions/loop-expr.md +++ b/src/expressions/loop-expr.md @@ -37,7 +37,7 @@ A `loop` expression repeats execution of its body continuously: `loop { println!("I live."); }`. A `loop` expression without an associated `break` expression is diverging and -has type [`!`](types.html#never-type). A `loop` expression containing +has type [`!`](types/never.html). A `loop` expression containing associated [`break` expression(s)](#break-expressions) may terminate, and must have type compatible with the value of the `break` expression(s). diff --git a/src/expressions/method-call-expr.md b/src/expressions/method-call-expr.md index 3b29ef024..fd150c352 100644 --- a/src/expressions/method-call-expr.md +++ b/src/expressions/method-call-expr.md @@ -9,7 +9,7 @@ dot, an expression path segment, and a parenthesized expression-list. Method cal resolved to associated [methods] on specific traits, either statically dispatching to a method if the exact `self`-type of the left-hand-side is known, or dynamically dispatching if the left-hand-side expression is an indirect -[trait object](types.html#trait-objects). +[trait object](types/trait-object.html). ```rust let pi: Result = "3.14".parse(); @@ -101,8 +101,8 @@ method and you'll be fine. [_Expression_]: expressions.html [_PathExprSegment_]: paths.html#paths-in-expressions [visible]: visibility-and-privacy.html -[array]: types.html#array-and-slice-types -[trait objects]: types.html#trait-objects +[array]: types/array.html +[trait objects]: types/trait-object.html [disambiguate call]: expressions/call-expr.html#disambiguating-function-calls [disambiguating function call syntax]: expressions/call-expr.html#disambiguating-function-calls [dereference]: expressions/operator-expr.html#the-dereference-operator diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index f3f9e4778..8cfbc7a07 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -85,7 +85,7 @@ let a = & & & & mut 10; >    `*` [_Expression_] The `*` (dereference) operator is also a unary prefix operator. When applied to -a [pointer](types.html#pointer-types) it denotes the pointed-to location. If +a [pointer](types/pointer.html) it denotes the pointed-to location. If the expression is of type `&mut T` and `*mut T`, and is either a local variable, a (nested) field of a local variable or is a mutable [place expression], then the resulting memory location can be assigned to. @@ -345,7 +345,7 @@ well as the following additional casts. Here `*T` means either `*const T` or | `*T` where `T: Sized` | Numeric type | Pointer to address cast | | Integer type | `*V` where `V: Sized` | Address to pointer cast | | `&[T; n]` | `*const T` | Array to pointer cast | -| [Function pointer](types.html#function-pointer-types) | `*V` where `V: Sized` | Function pointer to pointer cast | +| [Function pointer](types/function-pointer.html) | `*V` where `V: Sized` | Function pointer to pointer cast | | Function pointer | Integer | Function pointer to address cast | | Closure \*\* | Function pointer | Closure to function pointer cast | @@ -446,7 +446,7 @@ assert_eq!(x, 14); [temporary value]: expressions.html#temporary-lifetimes [float-int]: https://github.com/rust-lang/rust/issues/10184 [float-float]: https://github.com/rust-lang/rust/issues/15536 -[`unit` type]: types.html#tuple-types +[`unit` type]: types/tuple.html [_BorrowExpression_]: #borrow-operators [_DereferenceExpression_]: #the-dereference-operator @@ -460,4 +460,4 @@ assert_eq!(x, 14); [_CompoundAssignmentExpression_]: #compound-assignment-expressions [_Expression_]: expressions.html -[_TypeNoBounds_]: types.html +[_TypeNoBounds_]: types.html#type-expressions diff --git a/src/expressions/tuple-expr.md b/src/expressions/tuple-expr.md index 8739cb796..68bc9f438 100644 --- a/src/expressions/tuple-expr.md +++ b/src/expressions/tuple-expr.md @@ -10,7 +10,7 @@ >    ( [_Expression_] `,` )+ [_Expression_]? Tuples are written by enclosing zero or more comma-separated expressions in -parentheses. They are used to create [tuple-typed](types.html#tuple-types) +parentheses. They are used to create [tuple-typed](types/tuple.html) values. ```rust @@ -39,7 +39,7 @@ expressions]. > _TupleIndexingExpression_ :\ >    [_Expression_] `.` [TUPLE_INDEX] -[Tuples](types.html#tuple-types) and [struct tuples](items/structs.html) can be +[Tuples](types/tuple.html) and [struct tuples](items/structs.html) can be indexed using the number corresponding to the position of the field. The index must be written as a [decimal literal](tokens.html#integer-literals) with no underscores or suffix. Tuple indexing expressions also differ from field diff --git a/src/glossary.md b/src/glossary.md index 089b4c206..3fd11e8ac 100644 --- a/src/glossary.md +++ b/src/glossary.md @@ -134,7 +134,7 @@ Generic functions and generic structs can use traits to constrain, or bound, the [enums]: items/enumerations.html [structs]: items/structs.html [unions]: items/unions.html -[trait objects]: types.html#trait-objects +[trait objects]: types/trait-object.html [implementations]: items/implementations.html [traits]: items/traits.html [object safety]: items/traits.html#object-safety diff --git a/src/interior-mutability.md b/src/interior-mutability.md index f10d3679c..55f3caf48 100644 --- a/src/interior-mutability.md +++ b/src/interior-mutability.md @@ -20,7 +20,7 @@ borrow checks to ensure the usual rules around multiple references. The accessed with atomic operations, allowing the value to be shared and mutated across threads. -[shared reference]: types.html#shared-references- +[shared reference]: types/pointer.html#shared-references- [ub]: behavior-considered-undefined.html [`std::mem::transmute`]: ../std/mem/fn.transmute.html [`std::cell::UnsafeCell`]: ../std/cell/struct.UnsafeCell.html diff --git a/src/items/associated-items.md b/src/items/associated-items.md index 0aee1d741..2908e6bcc 100644 --- a/src/items/associated-items.md +++ b/src/items/associated-items.md @@ -292,20 +292,20 @@ fn main() { [_FunctionReturnType_]: items/functions.html [_Generics_]: items/generics.html [_Lifetime_]: trait-bounds.html -[_Type_]: types.html +[_Type_]: types.html#type-expressions [_WhereClause_]: items/generics.html#where-clauses [trait]: items/traits.html [traits]: items/traits.html [type aliases]: items/type-aliases.html [inherent implementations]: items/implementations.html#inherent-implementations [identifier]: identifiers.html -[trait object]: types.html#trait-objects +[trait object]: types/trait-object.html [implementations]: items/implementations.html -[type]: types.html +[type]: types.html#type-expressions [constants]: items/constant-items.html [constant item]: items/constant-items.html [functions]: items/functions.html -[function item]: types.html#function-item-types +[function item]: types/function-item.html [method call operator]: expressions/method-call-expr.html [block]: expressions/block-expr.html [path]: paths.html diff --git a/src/items/constant-items.md b/src/items/constant-items.md index 33e35a35a..ac3c0ebd4 100644 --- a/src/items/constant-items.md +++ b/src/items/constant-items.md @@ -64,5 +64,5 @@ fn create_and_drop_zero_with_destructor() { [static lifetime elision]: lifetime-elision.html#static-lifetime-elision [`Drop`]: special-types-and-traits.html#drop [IDENTIFIER]: identifiers.html -[_Type_]: types.html +[_Type_]: types.html#type-expressions [_Expression_]: expressions.html diff --git a/src/items/enumerations.md b/src/items/enumerations.md index c9cd187bf..0dc8064cc 100644 --- a/src/items/enumerations.md +++ b/src/items/enumerations.md @@ -137,7 +137,7 @@ enum ZeroVariants {} [_Expression_]: expressions.html [_TupleFields_]: items/structs.html [_StructFields_]: items/structs.html -[enumerated type]: types.html#enumerated-types +[enumerated type]: types/enum.html [`mem::discriminant`]: ../std/mem/fn.discriminant.html [numeric cast]: expressions/operator-expr.html#semantics [`repr` attribute]: attributes.html#ffi-attributes diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 4916ad5bb..b4f16b881 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -123,7 +123,7 @@ block. [_Generics_]: items/generics.html [_InnerAttribute_]: attributes.html [_OuterAttribute_]: attributes.html -[_Type_]: types.html +[_Type_]: types.html#type-expressions [_Visibility_]: visibility-and-privacy.html [_WhereClause_]: items/generics.html#where-clauses [attributes]: attributes.html#ffi-attributes diff --git a/src/items/functions.md b/src/items/functions.md index f37925a79..d0c5a2bcb 100644 --- a/src/items/functions.md +++ b/src/items/functions.md @@ -220,15 +220,15 @@ attributes macros. [_InnerAttribute_]: attributes.html [_Pattern_]: patterns.html [_Statement_]: statements.html -[_Type_]: types.html +[_Type_]: types.html#type-expressions [_WhereClause_]: items/generics.html#where-clauses [const contexts]: const_eval.html [external blocks]: items/external-blocks.html [path]: paths.html [block]: expressions/block-expr.html [variables]: variables.html -[type]: types.html -[*function item type*]: types.html#function-item-types +[type]: types.html#type-expressions +[*function item type*]: types/function-item.html [Trait]: items/traits.html [attributes]: attributes.html [`cfg`]: conditional-compilation.html diff --git a/src/items/generics.md b/src/items/generics.md index b52c68b14..bbadbf6e0 100644 --- a/src/items/generics.md +++ b/src/items/generics.md @@ -106,16 +106,16 @@ generic parameter. [_LifetimeBounds_]: trait-bounds.html [_Lifetime_]: trait-bounds.html [_OuterAttribute_]: attributes.html -[_Type_]: types.html +[_Type_]: types.html#type-expressions [_TypeParamBounds_]: trait-bounds.html -[arrays]: types.html#array-and-slice-types -[function pointers]: types.html#function-pointer-types -[references]: types.html#shared-references- -[raw pointers]: types.html#raw-pointers-const-and-mut +[arrays]: types/array.html +[function pointers]: types/function-pointer.html +[references]: types/pointer.html#shared-references- +[raw pointers]: types/pointer.html#raw-pointers-const-and-mut [`Clone`]: special-types-and-traits.html#clone [`Copy`]: special-types-and-traits.html#copy [`Sized`]: special-types-and-traits.html#sized -[tuples]: types.html#tuple-types -[trait object]: types.html#trait-objects +[tuples]: types/tuple.html +[trait object]: types/trait-object.html [attributes]: attributes.html diff --git a/src/items/implementations.md b/src/items/implementations.md index cab48572a..6e1352ff7 100644 --- a/src/items/implementations.md +++ b/src/items/implementations.md @@ -187,7 +187,7 @@ attributes]. [_OuterAttribute_]: attributes.html [_TypeAlias_]: items/type-aliases.html [_TypePath_]: paths.html#paths-in-types -[_Type_]: types.html +[_Type_]: types.html#type-expressions [_Visibility_]: visibility-and-privacy.html [_WhereClause_]: items/generics.html#where-clauses [trait]: items/traits.html diff --git a/src/items/static-items.md b/src/items/static-items.md index ead6947f4..bcb4b6d7b 100644 --- a/src/items/static-items.md +++ b/src/items/static-items.md @@ -73,5 +73,5 @@ following are true: [constant expression]: const_eval.html#constant-expressions [interior mutable]: interior-mutability.html [IDENTIFIER]: identifiers.html -[_Type_]: types.html +[_Type_]: types.html#type-expressions [_Expression_]: expressions.html diff --git a/src/items/structs.md b/src/items/structs.md index 4035923aa..6634afb29 100644 --- a/src/items/structs.md +++ b/src/items/structs.md @@ -49,8 +49,8 @@ let px: i32 = p.x; A _tuple struct_ is a nominal [tuple type], also defined with the keyword `struct`. For example: -[struct type]: types.html#struct-types -[tuple type]: types.html#tuple-types +[struct type]: types/struct.html +[tuple type]: types/tuple.html ```rust struct Point(i32, i32); @@ -85,4 +85,4 @@ particular layout using the [`repr` attribute]. [_Generics_]: items/generics.html [_WhereClause_]: items/generics.html#where-clauses [_Visibility_]: visibility-and-privacy.html -[_Type_]: types.html +[_Type_]: types.html#type-expressions diff --git a/src/items/traits.md b/src/items/traits.md index 4323ecd6b..7661315d1 100644 --- a/src/items/traits.md +++ b/src/items/traits.md @@ -216,10 +216,10 @@ trait T { [_Pattern_]: patterns.html [_SelfParam_]: items/associated-items.html#methods [_TypeParamBounds_]: trait-bounds.html -[_Type_]: types.html +[_Type_]: types.html#type-expressions [_WhereClause_]: items/generics.html#where-clauses [bounds]: trait-bounds.html -[trait object]: types.html#trait-objects +[trait object]: types/trait-object.html [explicit]: expressions/operator-expr.html#type-cast-expressions [RFC 255]: https://github.com/rust-lang/rfcs/blob/master/text/0255-object-safety.md [associated items]: items/associated-items.html diff --git a/src/items/type-aliases.md b/src/items/type-aliases.md index f85493b68..6ba22a87b 100644 --- a/src/items/type-aliases.md +++ b/src/items/type-aliases.md @@ -32,4 +32,4 @@ let _: F = E::A; // OK [IDENTIFIER]: identifiers.html [_Generics_]: items/generics.html [_WhereClause_]: items/generics.html#where-clauses -[_Type_]: types.html +[_Type_]: types.html#type-expressions diff --git a/src/keywords.md b/src/keywords.md index 4eee6b464..b732dd3b9 100644 --- a/src/keywords.md +++ b/src/keywords.md @@ -126,4 +126,4 @@ is possible to declare a variable or method with the name `union`. [Crates]: crates-and-source-files.html [union]: items/unions.html [variants]: items/enumerations.html -[`dyn`]: types.html#trait-objects +[`dyn`]: types/trait-object.html diff --git a/src/lifetime-elision.md b/src/lifetime-elision.md index eb43bd66c..e2414d13c 100644 --- a/src/lifetime-elision.md +++ b/src/lifetime-elision.md @@ -169,13 +169,13 @@ const RESOLVED_MULTIPLE: &dyn Fn(&Foo, &Bar, &Baz) -> usize = .. const RESOLVED_STATIC: &dyn Fn(&Foo, &Bar) -> &Baz = .. ``` -[closure trait]: types.html#closure-types +[closure trait]: types/closure.html [constant]: items/constant-items.html -[function item]: types.html#function-item-types -[function pointer]: types.html#function-pointer-types +[function item]: types/function-item.html +[function pointer]: types/function-pointer.html [implementation]: items/implementations.html [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 [static]: items/static-items.html -[trait object]: types.html#trait-objects +[trait object]: types/trait-object.html [type aliases]: items/type-aliases.html diff --git a/src/macros-by-example.md b/src/macros-by-example.md index 5e3fa88b5..30a7076c4 100644 --- a/src/macros-by-example.md +++ b/src/macros-by-example.md @@ -82,7 +82,7 @@ syntax named by _designator_. Valid designators are: [_Statement_]: statements.html [_TokenTree_]: macros.html#macro-invocation [_TypePath_]: paths.html#paths-in-types -[_Type_]: types.html +[_Type_]: types.html#type-expressions [_Visibility_]: visibility-and-privacy.html [token]: tokens.html diff --git a/src/paths.md b/src/paths.md index ddef50e86..d0fe535e8 100644 --- a/src/paths.md +++ b/src/paths.md @@ -185,24 +185,30 @@ fn bar() { ### `Self` -`Self` with a capital "S" is used to refer to a type relative to the current situation. +`Self` with a capital "S" is used to refer to the implementing type within +[traits] and [implementations]. -In a [trait] or [trait implementation] it refers to the type the trait is being -implemented for, or can be used to refer to an associated type or constant of the trait. +`Self` can only be used as the first segment, without a preceding `::`. ```rust trait T { type Item; const C: i32; + // `Self` will be whatever type that implements `T`. fn new() -> Self; + // `Self::Item` will be the type alias in the implementation. fn f(&self) -> Self::Item; } struct S; impl T for S { type Item = i32; const C: i32 = 9; - fn new() -> Self { S } - fn f(&self) -> Self::Item { Self::C } + fn new() -> Self { // `Self` is the type `S`. + S + } + fn f(&self) -> Self::Item { // `Self::Item` is the type `i32`. + Self::C // `Self::C` is the constant value `9`. + } } ``` @@ -348,7 +354,7 @@ mod without { // ::without [_GenericArgs_]: #paths-in-expressions [_Lifetime_]: trait-bounds.html -[_Type_]: types.html +[_Type_]: types.html#type-expressions [item]: items.html [variable]: variables.html [identifiers]: identifiers.html @@ -366,6 +372,6 @@ mod without { // ::without [struct]: items/structs.html [trait implementation]: items/implementations.html#trait-implementations [trait implementations]: items/implementations.html#trait-implementations -[trait]: items/traits.html +[traits]: items/traits.html [union]: items/unions.html [visibility]: visibility-and-privacy.html diff --git a/src/patterns.md b/src/patterns.md index 92da44467..bd881b13c 100644 --- a/src/patterns.md +++ b/src/patterns.md @@ -672,4 +672,4 @@ refer to refutable constants or enum variants for enums with multiple variants. [enums]: items/enumerations.html [literals]: expressions/literal-expr.html [structs]: items/structs.html -[tuples]: types.html#tuple-types +[tuples]: types/tuple.html diff --git a/src/special-types-and-traits.md b/src/special-types-and-traits.md index 90f36b2e1..f78686fbe 100644 --- a/src/special-types-and-traits.md +++ b/src/special-types-and-traits.md @@ -139,29 +139,29 @@ compiler, not by [implementation items]. [`UnwindSafe`]: ../std/panic/trait.UnwindSafe.html [`Sync`]: ../std/marker/trait.Sync.html -[Arrays]: types.html#array-and-slice-types +[Arrays]: types/array.html [call expressions]: expressions/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 +[Function pointers]: types/function-pointer.html +[function item types]: types/function-item.html [implementation items]: items/implementations.html [indexing expressions]: expressions/array-expr.html#array-and-slice-indexing-expressions [interior mutability]: interior-mutability.html -[Numeric types]: types.html#numeric-types +[Numeric types]: types/numeric.html [Methods]: items/associated-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 +[Raw pointers]: types/pointer.html#raw-pointers-const-and-mut [`static` items]: items/static-items.html -[Shared references]: types.html#shared-references- +[Shared references]: types/pointer.html#shared-references- [the standard library]: ../std/index.html -[trait object]: types.html#trait-objects -[Tuples]: types.html#tuple-types +[trait object]: types/trait-object.html +[Tuples]: types/tuple.html [Type parameters]: types.html#type-parameters [variance]: subtyping.html#variance -[`!`]: types.html#never-type +[`!`]: types/never.html diff --git a/src/subtyping.md b/src/subtyping.md index 1d42a83c8..6a9c5e26a 100644 --- a/src/subtyping.md +++ b/src/subtyping.md @@ -83,7 +83,7 @@ struct Variance<'a, 'b, T, U: 'a> { ``` [coercions]: type-coercions.html -[function pointers]: types.html#function-pointer-types +[function pointers]: types/function-pointer.html [Higher-ranked]: ../nomicon/hrtb.html -[lifetime bound]: types.html#trait-object-lifetime-bounds -[trait objects]: types.html#trait-objects +[lifetime bound]: types/trait-object.html#trait-object-lifetime-bounds +[trait objects]: types/trait-object.html diff --git a/src/tokens.md b/src/tokens.md index b4ab56cc4..13ef1e458 100644 --- a/src/tokens.md +++ b/src/tokens.md @@ -483,7 +483,7 @@ to call a method named `f64` on `2`. The representation semantics of floating-point numbers are described in ["Machine Types"]. -["Machine Types"]: types.html#machine-types +["Machine Types"]: types/numeric.html ### Boolean literals @@ -583,7 +583,7 @@ them are referred to as "token trees" in [macros]. The three types of brackets [Subpattern binding]: patterns.html#identifier-patterns [Wildcard patterns]: patterns.html#wildcard-pattern [arith]: expressions/operator-expr.html#arithmetic-and-logical-binary-operators -[array types]: types.html#array-and-slice-types +[array types]: types/array.html [assignment]: expressions/operator-expr.html#assignment-expressions [attributes]: attributes.html [borrow]: expressions/operator-expr.html#borrow-operators @@ -602,13 +602,13 @@ them are referred to as "token trees" in [macros]. The three types of brackets [macros]: macros-by-example.html [match]: expressions/match-expr.html [negation]: expressions/operator-expr.html#negation-operators -[never type]: types.html#never-type +[never type]: types/never.html [paths]: paths.html [patterns]: patterns.html [question]: expressions/operator-expr.html#the-question-mark-operator [range]: expressions/range-expr.html -[raw pointers]: types.html#raw-pointers-const-and-mut -[references]: types.html#pointer-types +[raw pointers]: types/pointer.html#raw-pointers-const-and-mut +[references]: types/pointer.html [sized]: trait-bounds.html#sized [struct expressions]: expressions/struct-expr.html [tokens]: #tokens @@ -616,4 +616,4 @@ them are referred to as "token trees" in [macros]. The three types of brackets [tuple index]: expressions/tuple-expr.html#tuple-indexing-expressions [tuple structs]: items/structs.html [tuple variants]: items/enumerations.html -[tuples]: types.html#tuple-types +[tuples]: types/tuple.html diff --git a/src/trait-bounds.md b/src/trait-bounds.md index dfcc313db..cbdaf958a 100644 --- a/src/trait-bounds.md +++ b/src/trait-bounds.md @@ -142,5 +142,5 @@ fn call_on_ref_zero(f: F) where F: for<'a> Fn(&'a i32) { [supertraits]: items/traits.html#supertraits [generic]: items/generics.html [Trait]: items/traits.html#trait-bounds -[trait objects]: types.html#trait-objects +[trait objects]: types/trait-object.html [where clause]: items/generics.html#where-clauses diff --git a/src/types-redirect.html b/src/types-redirect.html new file mode 100644 index 000000000..e1185ffed --- /dev/null +++ b/src/types-redirect.html @@ -0,0 +1,41 @@ + diff --git a/src/types.md b/src/types.md index 59203a726..28ebdbd87 100644 --- a/src/types.md +++ b/src/types.md @@ -1,5 +1,43 @@ +{{#include types-redirect.html}} # Types +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 and the operations +that may be performed on the value. + +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. + +The list of types is: + +* Primitive types: + * [Boolean] — `true` or `false` + * [Numeric] — integer and float + * [Textual] — `char` and `str` + * [Never] — `!` — a type with no value +* Sequence types: + * [Tuple] + * [Array] + * [Slice] +* User-defined types: + * [Struct] + * [Enum] + * [Union] +* Function types: + * [Functions] + * [Closures] +* Pointer types: + * [References] + * [Raw pointers] + * [Function pointers] +* Trait types: + * [Trait objects] + * [Impl trait] + + +## Type expressions + > **Syntax**\ > _Type_ :\ >       _TypeNoBounds_\ @@ -22,736 +60,41 @@ >    | [_BareFunctionType_]\ >    | [_MacroInvocation_] -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 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 - -Some types are defined by the language, rather than as part of the standard -library, these are called _primitive types_. Some of these are individual -types: - -* The [boolean type] `bool` with values `true` and `false`. -* The [machine types] (integer and floating-point). -* The [machine-dependent integer types]. -* The [textual types] `char` and `str`. -* The [never type] `!` - -There are also some primitive constructs for generic types built in to the -language: - -* [Tuples] -* [Arrays] -* [Slices] -* [Function pointers] -* [References] -* [Pointers] - -[boolean type]: #boolean-type -[machine types]: #machine-types -[machine-dependent integer types]: #machine-dependent-integer-types -[textual types]: #textual-types -[never type]: #never-type -[Tuples]: #tuple-types -[Arrays]: #array-and-slice-types -[Slices]: #array-and-slice-types -[References]: #pointer-types -[Pointers]: #raw-pointers-const-and-mut -[Function pointers]: #function-pointer-types -[function]: #function-types -[closure]: #closure-types - -### Boolean type - -The `bool` type is a datatype which can be either `true` or `false`. The boolean -type uses one byte of memory. It is used in comparisons and bitwise operations -like `&`, `|`, and `!`. - -```rust -fn main() { - let x = true; - let y: bool = false; // with the boolean type annotation - - // Use of booleans in conditional expressions - if x { - println!("x is true"); - } -} -``` - -## Numeric types - -### Machine types - -The machine types are the following: - -* The unsigned word types `u8`, `u16`, `u32`, `u64`, and `u128` with values - drawn from the integer intervals [0, 2^8 - 1], [0, 2^16 - 1], [0, 2^32 - 1], - [0, 2^64 - 1], and [0, 2^128 - 1] respectively. - -* The signed two's complement word types `i8`, `i16`, `i32`, `i64`, and `i128`, - with values drawn from the integer intervals [-(2^7), 2^7 - 1], - [-(2^15), 2^15 - 1], [-(2^31), 2^31 - 1], [-(2^63), 2^63 - 1], and - [-(2^127), 2^127 - 1] respectively. - -* The IEEE 754-2008 "binary32" and "binary64" floating-point types: `f32` and - `f64`, respectively. - -### Machine-dependent integer types - -The `usize` type is an unsigned integer type with the same number of bits as the -platform's pointer type. It can represent every memory address in the process. - -The `isize` type is a signed integer type with the same number of bits as the -platform's pointer type. The theoretical upper bound on object and array size -is the maximum `isize` value. This ensures that `isize` can be used to calculate -differences between pointers into an object or array and can address every byte -within an object along with one byte past the end. - -## Textual types - -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]` 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 a -[dynamically sized type], it is not a _first-class_ type, but can only be -instantiated through a pointer type, such as `&str`. +A _type expression_ as defined in the _Type_ grammar rule above is the syntax +for referring to a type. It may refer to: -## Never type +* Sequence types ([tuple], [array], [slice]). +* [Type paths] which can reference: + * Primitive types ([boolean], [numeric], [textual]). + * Paths to an [item] ([struct], [enum], [union], [type alias], [trait]). + * [`Self` path] where `Self` is the implementing type. + * Generic [type parameters]. +* Pointer types ([reference], [raw pointer], [function pointer]). +* The [inferred type] which asks the compiler to determine the type. +* [Parentheses] which are used for disambiguation. +* Trait types: [Trait objects] and [impl trait]. +* The [never] type. +* [Macros] which expand to a type expression. -> **Syntax**\ -> _NeverType_ : `!` - -The never type `!` is a type with no values, representing the result of -computations that never complete. Expressions of type `!` can be coerced into -any other type. - -## Tuple types - -> **Syntax**\ -> _TupleType_ :\ ->       `(` `)`\ ->    | `(` ( [_Type_] `,` )+ [_Type_]? `)` - -A tuple *type* is a heterogeneous product of other types, called the *elements* -of the tuple. It has no nominal name and is instead structurally typed. - -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. -An example of a tuple type and its use: - -```rust -type Pair<'a> = (i32, &'a str); -let p: Pair<'static> = (10, "ten"); -let (a, b) = p; - -assert_eq!(a, 10); -assert_eq!(b, "ten"); -assert_eq!(p.0, 10); -assert_eq!(p.1, "ten"); -``` - -For historical reasons and convenience, the tuple type with no elements (`()`) -is often called ‘unit’ or ‘the unit type’. - -## Parenthesized types +### Parenthesized types > _ParenthesizedType_ :\ >    `(` [_Type_] `)` In some situations the combination of types may be ambiguous. Use parentheses around a type to avoid ambiguity. For example, the `+` operator for [type -boundaries] within a [reference type][_ReferenceType_] is unclear where the +boundaries] within a [reference type] is unclear where the boundary applies, so the use of parentheses is required. Grammar rules that require this disambiguation use the [_TypeNoBounds_] rule instead of [_Type_]. - ```rust # use std::any::Any; type T<'a> = &'a(Any + Send); ``` -## Array, and Slice types - -> **Syntax**\ -> _ArrayType_ :\ ->    `[` [_Type_] `;` [_Expression_] `]` -> -> _SliceType_ :\ ->    `[` [_Type_] `]` - -Rust has two different types for a list of items of the same type: - -* `[T; N]`, an 'array' -* `[T]`, a 'slice' - -An array has a fixed size, and can be allocated on either the stack or the -heap. The size is an expression that evaluates to a -[`usize`](#machine-dependent-integer-types). - -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: - -```rust -// A stack-allocated array -let array: [i32; 3] = [1, 2, 3]; - -// A heap-allocated array, coerced to a slice -let boxed_array: Box<[i32]> = Box::new([1, 2, 3]); - -// A (shared) slice into an array -let slice: &[i32] = &boxed_array[..]; -``` - -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. - -> Note: The [`Vec`] standard library type provides a heap-allocated resizable -> array type. - -## Struct types - -A `struct` *type* is a heterogeneous product of other types, called the -*fields* of the type.[^structtype] - -New instances of a `struct` can be constructed with a [struct -expression](expressions/struct-expr.html). - -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 -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. - -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] 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/enumerations.html). [^enumtype] - -An [`enum` item](items/enumerations.html) 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/enum-variant-expr.html). - -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/enumerations.html). - -[^enumtype]: The `enum` type is analogous to a `data` constructor declaration in - ML, or a *pick ADT* in Limbo. - -## Union types - -A *union type* is a nominal, heterogeneous C-like union, denoted by the name of -a [`union` item](items/unions.html). - -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`]. - -The memory layout of a `union` is undefined by default, but the `#[repr(...)]` -attribute can be used to fix a layout. - -[`Copy`]: special-types-and-traits.html#copy - -## Recursive types - -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: - -```rust -enum List { - Nil, - Cons(T, Box>) -} - -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 moved or -copied, stored into data structs, and returned from functions. - -### Shared references (`&`) - -> **Syntax**\ -> _ReferenceType_ :\ ->    `&` [_Lifetime_]? `mut`? [_TypeNoBounds_] - -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`) - -> **Syntax**\ -> _RawPointerType_ :\ ->    `*` ( `mut` | `const` ) [_TypeNoBounds_] - -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, 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 no syntax that directly refers to a function item type, but the -compiler will display the type as something like `fn(u32) -> i32 {fn_name}` 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,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`: - -[coercion]: type-coercions.html - -```rust -# let want_i32 = false; -# fn foo() { } - -// `foo_ptr_1` has function pointer type `fn()` here -let foo_ptr_1: fn() = foo::; - -// ... and so does `foo_ptr_2` - this type-checks. -let foo_ptr_2 = if want_i32 { - foo:: -} else { - foo:: -}; -``` - -All function items implement [`Fn`], [`FnMut`], [`FnOnce`], [`Copy`], -[`Clone`], [`Send`], and [`Sync`]. - -## Function pointer types - -> **Syntax**\ -> _BareFunctionType_ :\ ->    [_ForLifetimes_]? [_FunctionQualifiers_] `fn`\ ->       `(` _FunctionParametersMaybeNamedVariadic_? `)` _BareFunctionReturnType_? -> -> _BareFunctionReturnType_:\ ->    `->` [_TypeNoBounds_] -> -> _FunctionParametersMaybeNamedVariadic_ :\ ->    _MaybeNamedFunctionParameters_ | _MaybeNamedFunctionParametersVariadic_ -> -> _MaybeNamedFunctionParameters_ :\ ->    _MaybeNamedParam_ ( `,` _MaybeNamedParam_ )\* `,`? -> -> _MaybeNamedParam_ :\ ->    ( ( [IDENTIFIER] | `_` ) `:` )? [_Type_] -> -> _MaybeNamedFunctionParametersVariadic_ :\ ->    ( _MaybeNamedParam_ `,` )\* _MaybeNamedParam_ `,` `...` - -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. - -Variadic parameters can only be specified with [`extern`] function types with -the `"C"` or `"cdecl"` calling convention. - -An example where `Binop` is defined as a function pointer type: - -```rust -fn add(x: i32, y: i32) -> i32 { - x + y -} - -let mut x = add(5,7); - -type Binop = fn(i32, i32) -> i32; -let bo: Binop = add; -x = bo(5,7); -``` - -## Closure types - -A [closure expression] produces a closure value with a unique, anonymous type -that cannot be written out. A closure type is approximately equivalent to a -struct which contains the captured variables. For instance, the following -closure: - -```rust -fn f String> (g: F) { - println!("{}", g()); -} - -let mut s = String::from("foo"); -let t = String::from("bar"); - -f(|| { - s += &*t; - s -}); -// Prints "foobar". -``` - -generates a closure type roughly like the following: - -```rust,ignore -struct Closure<'a> { - s : String, - t : &'a String, -} - -impl<'a> (FnOnce() -> String) for Closure<'a> { - fn call_once(self) -> String { - self.s += &*self.t; - self.s - } -} -``` - -so that the call to `f` works as if it were: - -```rust,ignore -f(Closure{s: s, t: &t}); -``` - -### Capture modes - -The compiler prefers to capture a closed-over variable by immutable borrow, -followed by unique immutable borrow (see below), by mutable borrow, and finally -by move. It will pick the first choice of these that allows the closure to -compile. The choice is made only with regards to the contents of the closure -expression; the compiler does not take into account surrounding code, such as -the lifetimes of involved variables. - -If the `move` keyword is used, then all captures are by move or, for `Copy` -types, by copy, regardless of whether a borrow would work. The `move` keyword is -usually used to allow the closure to outlive the captured values, such as if the -closure is being returned or used to spawn a new thread. - -Composite types such as structs, tuples, and enums are always captured entirely, -not by individual fields. It may be necessary to borrow into a local variable in -order to capture a single field: - -```rust -# use std::collections::HashSet; -# -struct SetVec { - set: HashSet, - vec: Vec -} - -impl SetVec { - fn populate(&mut self) { - let vec = &mut self.vec; - self.set.iter().for_each(|&n| { - vec.push(n); - }) - } -} -``` - -If, instead, the closure were to use `self.vec` directly, then it would attempt -to capture `self` by mutable reference. But since `self.set` is already -borrowed to iterate over, the code would not compile. - -### Unique immutable borrows in captures - -Captures can occur by a special kind of borrow called a _unique immutable -borrow_, which cannot be used anywhere else in the language and cannot be -written out explicitly. It occurs when modifying the referent of a mutable -reference, as in the following example: - -```rust -let mut b = false; -let x = &mut b; -{ - let mut c = || { *x = true; }; - // The following line is an error: - // let y = &x; - c(); -} -let z = &x; -``` - -In this case, borrowing `x` mutably is not possible, because `x` is not `mut`. -But at the same time, borrowing `x` immutably would make the assignment illegal, -because a `& &mut` reference may not be unique, so it cannot safely be used to -modify a value. So a unique immutable borrow is used: it borrows `x` immutably, -but like a mutable borrow, it must be unique. In the above example, uncommenting -the declaration of `y` will produce an error because it would violate the -uniqueness of the closure's borrow of `x`; the declaration of z is valid because -the closure's lifetime has expired at the end of the block, releasing the borrow. - -### Call traits and coercions - -Closure types all implement [`FnOnce`], indicating that they can be called once -by consuming ownership of the closure. Additionally, some closures implement -more specific call traits: - -* A closure which does not move out of any captured variables implements - [`FnMut`], indicating that it can be called by mutable reference. - -* A closure which does not mutate or move out of any captured variables - implements [`Fn`], indicating that it can be called by shared reference. - -> Note: `move` closures may still implement [`Fn`] or [`FnMut`], even though -> they capture variables by move. This is because the traits implemented by a -> closure type are determined by what the closure does with captured values, -> not how it captures them. - -*Non-capturing closures* are closures that don't capture anything from their -environment. They can be coerced to function pointers (`fn`) with the matching -signature. - -```rust -let add = |x, y| x + y; - -let mut x = add(5,7); - -type Binop = fn(i32, i32) -> i32; -let bo: Binop = add; -x = bo(5,7); -``` - -### Other traits - -All closure types implement [`Sized`]. Additionally, closure types implement the -following traits if allowed to do so by the types of the captures it stores: - -* [`Clone`] -* [`Copy`] -* [`Sync`] -* [`Send`] - -The rules for [`Send`] and [`Sync`] match those for normal struct types, while -[`Clone`] and [`Copy`] behave as if [derived][derive]. For [`Clone`], the order -of cloning of the captured variables is left unspecified. - -Because captures are often by reference, the following general rules arise: - -* A closure is [`Sync`] if all captured variables are [`Sync`]. -* A closure is [`Send`] if all variables captured by non-unique immutable - reference are [`Sync`], and all values captured by unique immutable or mutable - reference, copy, or move are [`Send`]. -* A closure is [`Clone`] or [`Copy`] if it does not capture any values by - unique immutable or mutable reference, and if all values it captures by copy - or move are [`Clone`] or [`Copy`], respectively. - -## Trait objects - -> **Syntax**\ -> _TraitObjectType_ :\ ->    `dyn`? [_TypeParamBounds_] -> -> _TraitObjectTypeOneBound_ :\ ->    `dyn`? [_TraitBound_] - -A *trait object* is an opaque value of another type that implements a set of -traits. The set of traits is made up of an [object safe] *base trait* plus any -number of [auto traits]. - -Trait objects implement the base trait, its auto traits, and any [supertraits] -of the base trait. - -Trait objects are written as the optional keyword `dyn` followed by a set of -trait bounds, but with the following restrictions on the trait bounds. All -traits except the first trait must be auto traits, there may not be more than -one lifetime, and opt-out bounds (e.g. `?sized`) are not allowed. Furthermore, -paths to traits may be parenthesized. - -For example, given a trait `Trait`, the following are all trait objects: - -* `Trait` -* `dyn Trait` -* `dyn Trait + Send` -* `dyn Trait + Send + Sync` -* `dyn Trait + 'static` -* `dyn Trait + Send + 'static` -* `dyn Trait +` -* `dyn 'static + Trait`. -* `dyn (Trait)` - -> **Edition Differences**: In the 2015 edition, if the first bound of the -> trait object is a path that starts with `::`, then the `dyn` will be treated -> as a part of the path. The first path can be put in parenthesis to get -> around this. As such, if you want a trait object with the trait -> `::your_module::Trait`, you should write it as `dyn (::your_module::Trait)`. -> -> Beginning in the 2018 edition, `dyn` is a true keyword and is not allowed in -> paths, so the parentheses are not necessary. - -> Note: For clarity, it is recommended to always use the `dyn` keyword on your -> trait objects unless your codebase supports compiling with Rust 1.26 or lower. - -Two trait object types alias each other if the base traits alias each other and -if the sets of auto traits are the same and the lifetime bounds are the same. -For example, `dyn Trait + Send + UnwindSafe` is the same as -`dyn Trait + Unwindsafe + Send`. - -
- -***Warning:*** With two trait object types, even when the complete set of traits -is the same, if the base traits differ, the type is different. For example, -`dyn Send + Sync` is a different type from `dyn Sync + Send`. See [issue 33140]. - -
- -Due to the opaqueness of which concrete type the value is of, trait objects are -[dynamically sized types]. Like all -DSTs, trait objects are used -behind some type of pointer; for example `&dyn SomeTrait` or -`Box`. Each instance of a pointer to a trait object includes: - - - a pointer to an instance of a type `T` that implements `SomeTrait` - - a _virtual method table_, often just called a _vtable_, which contains, for - each method of `SomeTrait` and its [supertraits] that `T` implements, a - pointer to `T`'s implementation (i.e. a function pointer). - -The purpose of trait objects is to permit "late binding" of methods. Calling a -method on a trait object results in virtual dispatch at runtime: that is, a -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. - -An example of a trait object: - -```rust -trait Printable { - fn stringify(&self) -> String; -} - -impl Printable for i32 { - fn stringify(&self) -> String { self.to_string() } -} - -fn print(a: Box) { - println!("{}", a.stringify()); -} - -fn main() { - print(Box::new(10) as Box); -} -``` - -In this example, the trait `Printable` occurs as a trait object in both the -type signature of `print`, and the cast expression in `main`. - -### Trait Object Lifetime Bounds - -Since a trait object can contain references, the lifetimes of those references -need to be expressed as part of the trait object. This lifetime is written as -`Trait + 'a`. There are [defaults] that allow this lifetime to usually be -inferred with a sensible choice. - -[defaults]: lifetime-elision.html#default-trait-object-lifetimes - -## Inferred type +### Inferred type > **Syntax**\ > _InferredType_ : `_` @@ -769,7 +112,8 @@ let x: Vec<_> = (0..10).collect(); There should be a broader discussion of type inference somewhere. --> -## Type parameters + +### Type parameters Within the body of an item that has type parameter declarations, the names of its type parameters are types: @@ -789,119 +133,88 @@ 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`. -## Impl trait -> **Syntax**\ -> _ImplTraitType_ : `impl` [_TypeParamBounds_] -> -> _ImplTraitTypeOneBound_ : `impl` [_TraitBound_] - -### Anonymous type parameters - -> Note: This section is a placeholder for more comprehensive reference -> material. - -> Note: This is often called "impl Trait in argument position". - -Functions can declare an argument to be an anonymous type parameter where the -callee must provide a type that has the bounds declared by the anonymous type -parameter and the function can only use the methods available by the trait -bounds of the anonymous type parameter. - -They are written as `impl` followed by a set of trait bounds. - -### Abstract return types - -> Note: This section is a placeholder for more comprehensive reference -> material. - -> Note: This is often called "impl Trait in return position". - -Functions, except for associated trait functions, can return an abstract -return type. These types stand in for another concrete type where the -use-site may only use the trait methods declared by the trait bounds of the -type. - -They are written as `impl` followed by a set of trait bounds. - -## Self types - -The special type `Self` has a meaning within traits and implementations: it -refers to the implementing type. For example, in: +## Recursive types -```rust -pub trait From { - fn from(T) -> Self; -} +Nominal types — [structs], [enumerations] and [unions] — 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: -impl From for String { - fn from(x: i32) -> Self { - x.to_string() - } -} -``` +* Recursive types must include a nominal type in the recursion (not mere [type + aliases], or other structural types such as [arrays] or [tuples]). 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]. +* 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). -The notation `Self` in the impl refers to the implementing type: `String`. In -another example: +An example of a *recursive* type and its use: ```rust -trait Printable { - fn make_string(&self) -> String; +enum List { + Nil, + Cons(T, Box>) } -impl Printable for String { - fn make_string(&self) -> String { - (*self).clone() - } -} +let a: List = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil)))); ``` -> Note: The notation `&self` is a shorthand for `self: &Self`. - -[IDENTIFIER]: identifiers.html -[_ArrayType_]: #array-and-slice-types -[_BareFunctionType_]: #function-pointer-types -[_Expression_]: expressions.html -[_ForLifetimes_]: items/generics.html#where-clauses -[_FunctionParametersMaybeNamed_]: items/functions.html -[_FunctionQualifiers_]: items/functions.html -[_ImplTraitTypeOneBound_]: #impl-trait -[_ImplTraitType_]: #impl-trait -[_InferredType_]: #inferred-type -[_Lifetime_]: trait-bounds.html +[_ArrayType_]: types/array.html +[_BareFunctionType_]: types/function-pointer.html +[_ImplTraitTypeOneBound_]: types/impl-trait.html +[_ImplTraitType_]: types/impl-trait.html +[_InferredType_]: types.html#inferred-type [_MacroInvocation_]: macros.html#macro-invocation -[_NeverType_]: #never-type -[_ParenthesizedType_]: #parenthesized-types +[_NeverType_]: types/never.html +[_ParenthesizedType_]: types.html#parenthesized-types [_QualifiedPathInType_]: paths.html#qualified-paths -[_RawPointerType_]: #raw-pointers-const-and-mut -[_ReferenceType_]: #shared-references- -[_SliceType_]: #array-and-slice-types -[_TraitBound_]: trait-bounds.html -[_TraitObjectTypeOneBound_]: #trait-objects -[_TraitObjectType_]: #trait-objects -[_TupleType_]: #tuple-types -[_TypeNoBounds_]: #types -[_TypeParamBounds_]: trait-bounds.html +[_RawPointerType_]: types/pointer.html#raw-pointers-const-and-mut +[_ReferenceType_]: types/pointer.html#shared-references- +[_SliceType_]: types/slice.html +[_TraitObjectTypeOneBound_]: types/trait-object.html +[_TraitObjectType_]: types/trait-object.html +[_TupleType_]: types/tuple.html#tuple-types +[_TypeNoBounds_]: types.html#type-expressions [_TypePath_]: paths.html#paths-in-types -[_Type_]: #types -[`Fn`]: ../std/ops/trait.Fn.html -[`FnMut`]: ../std/ops/trait.FnMut.html -[`FnOnce`]: ../std/ops/trait.FnOnce.html -[`Copy`]: special-types-and-traits.html#copy -[`Clone`]: special-types-and-traits.html#clone -[`Send`]: special-types-and-traits.html#send -[`Sync`]: special-types-and-traits.html#sync -[`Sized`]: special-types-and-traits.html#sized -[`extern`]: items/external-blocks.html -[derive]: attributes.html#derive -[`Vec`]: ../std/vec/struct.Vec.html -[dynamically sized type]: dynamically-sized-types.html -[dynamically sized types]: dynamically-sized-types.html -[struct expression]: expressions/struct-expr.html -[closure expression]: expressions/closure-expr.html -[auto traits]: special-types-and-traits.html#auto-traits -[object safe]: items/traits.html#object-safety -[issue 47010]: https://github.com/rust-lang/rust/issues/47010 -[issue 33140]: https://github.com/rust-lang/rust/issues/33140 -[supertraits]: items/traits.html#supertraits +[_Type_]: types.html#type-expressions + +[Array]: types/array.html +[Boolean]: types/boolean.html +[Closures]: types/closure.html +[Enum]: types/enum.html +[Function pointers]: types/function-pointer.html +[Functions]: types/function-item.html +[Impl trait]: types/impl-trait.html +[Macros]: macros.html +[Numeric]: types/numeric.html +[Parentheses]: #parenthesized-types +[Raw pointers]: types/pointer.html#raw-pointers-const-and-mut +[References]: types/pointer.html#shared-references- +[Slice]: types/slice.html +[Struct]: types/struct.html +[Textual]: types/textual.html +[Trait objects]: types/trait-object.html +[Tuple]: types/tuple.html +[Type paths]: paths.html#paths-in-types +[Union]: types/union.html +[`Self` path]: paths.html#self-1 +[arrays]: types/array.html +[enumerations]: types/enum.html +[function pointer]: types/function-pointer.html +[inferred type]: types.html#inferred-type +[item]: items.html +[never]: types/never.html +[pointer types]: types/pointer.html +[raw pointer]: types/pointer.html#raw-pointers-const-and-mut +[reference type]: types/pointer.html#shared-references- +[reference]: types/pointer.html#shared-references- +[structs]: types/struct.html +[trait]: types/trait-object.html +[tuples]: types/tuple.html +[type alias]: items/type-aliases.html +[type aliases]: items/type-aliases.html [type boundaries]: trait-bounds.html +[type parameters]: #type-parameters +[unions]: types/union.html diff --git a/src/types/array.md b/src/types/array.md new file mode 100644 index 000000000..eca0c82be --- /dev/null +++ b/src/types/array.md @@ -0,0 +1,32 @@ +# Array types + +> **Syntax**\ +> _ArrayType_ :\ +>    `[` [_Type_] `;` [_Expression_] `]` + +An array is a fixed-size sequence of `N` elements of type `T`. The array type +is written as `[T; N]`. + +An array can be allocated on either the stack or the heap. The size is an +expression that evaluates to a [`usize`]. + +Examples: + +```rust +// A stack-allocated array +let array: [i32; 3] = [1, 2, 3]; + +// A heap-allocated array, coerced to a slice +let boxed_array: Box<[i32]> = Box::new([1, 2, 3]); +``` + +All elements of arrays are always initialized, and access to an array is +always bounds-checked in safe methods and operators. + +> Note: The [`Vec`] standard library type provides a heap-allocated resizable +> array type. + +[_Expression_]: expressions.html +[_Type_]: types.html#type-expressions +[`Vec`]: ../std/vec/struct.Vec.html +[`usize`]: types/numeric.html#machine-dependent-integer-types diff --git a/src/types/boolean.md b/src/types/boolean.md new file mode 100644 index 000000000..6c976b2a5 --- /dev/null +++ b/src/types/boolean.md @@ -0,0 +1,17 @@ +# Boolean type + +The `bool` type is a datatype which can be either `true` or `false`. The boolean +type uses one byte of memory. It is used in comparisons and bitwise operations +like `&`, `|`, and `!`. + +```rust +fn main() { + let x = true; + let y: bool = false; // with the boolean type annotation + + // Use of booleans in conditional expressions + if x { + println!("x is true"); + } +} +``` diff --git a/src/types/closure.md b/src/types/closure.md new file mode 100644 index 000000000..785b78fbe --- /dev/null +++ b/src/types/closure.md @@ -0,0 +1,177 @@ +# Closure types + +A [closure expression] produces a closure value with a unique, anonymous type +that cannot be written out. A closure type is approximately equivalent to a +struct which contains the captured variables. For instance, the following +closure: + +```rust +fn f String> (g: F) { + println!("{}", g()); +} + +let mut s = String::from("foo"); +let t = String::from("bar"); + +f(|| { + s += &*t; + s +}); +// Prints "foobar". +``` + +generates a closure type roughly like the following: + +```rust,ignore +struct Closure<'a> { + s : String, + t : &'a String, +} + +impl<'a> (FnOnce() -> String) for Closure<'a> { + fn call_once(self) -> String { + self.s += &*self.t; + self.s + } +} +``` + +so that the call to `f` works as if it were: + +```rust,ignore +f(Closure{s: s, t: &t}); +``` + +## Capture modes + +The compiler prefers to capture a closed-over variable by immutable borrow, +followed by unique immutable borrow (see below), by mutable borrow, and finally +by move. It will pick the first choice of these that allows the closure to +compile. The choice is made only with regards to the contents of the closure +expression; the compiler does not take into account surrounding code, such as +the lifetimes of involved variables. + +If the `move` keyword is used, then all captures are by move or, for `Copy` +types, by copy, regardless of whether a borrow would work. The `move` keyword is +usually used to allow the closure to outlive the captured values, such as if the +closure is being returned or used to spawn a new thread. + +Composite types such as structs, tuples, and enums are always captured entirely, +not by individual fields. It may be necessary to borrow into a local variable in +order to capture a single field: + +```rust +# use std::collections::HashSet; +# +struct SetVec { + set: HashSet, + vec: Vec +} + +impl SetVec { + fn populate(&mut self) { + let vec = &mut self.vec; + self.set.iter().for_each(|&n| { + vec.push(n); + }) + } +} +``` + +If, instead, the closure were to use `self.vec` directly, then it would attempt +to capture `self` by mutable reference. But since `self.set` is already +borrowed to iterate over, the code would not compile. + +## Unique immutable borrows in captures + +Captures can occur by a special kind of borrow called a _unique immutable +borrow_, which cannot be used anywhere else in the language and cannot be +written out explicitly. It occurs when modifying the referent of a mutable +reference, as in the following example: + +```rust +let mut b = false; +let x = &mut b; +{ + let mut c = || { *x = true; }; + // The following line is an error: + // let y = &x; + c(); +} +let z = &x; +``` + +In this case, borrowing `x` mutably is not possible, because `x` is not `mut`. +But at the same time, borrowing `x` immutably would make the assignment illegal, +because a `& &mut` reference may not be unique, so it cannot safely be used to +modify a value. So a unique immutable borrow is used: it borrows `x` immutably, +but like a mutable borrow, it must be unique. In the above example, uncommenting +the declaration of `y` will produce an error because it would violate the +uniqueness of the closure's borrow of `x`; the declaration of z is valid because +the closure's lifetime has expired at the end of the block, releasing the borrow. + +## Call traits and coercions + +Closure types all implement [`FnOnce`], indicating that they can be called once +by consuming ownership of the closure. Additionally, some closures implement +more specific call traits: + +* A closure which does not move out of any captured variables implements + [`FnMut`], indicating that it can be called by mutable reference. + +* A closure which does not mutate or move out of any captured variables + implements [`Fn`], indicating that it can be called by shared reference. + +> Note: `move` closures may still implement [`Fn`] or [`FnMut`], even though +> they capture variables by move. This is because the traits implemented by a +> closure type are determined by what the closure does with captured values, +> not how it captures them. + +*Non-capturing closures* are closures that don't capture anything from their +environment. They can be coerced to function pointers (`fn`) with the matching +signature. + +```rust +let add = |x, y| x + y; + +let mut x = add(5,7); + +type Binop = fn(i32, i32) -> i32; +let bo: Binop = add; +x = bo(5,7); +``` + +## Other traits + +All closure types implement [`Sized`]. Additionally, closure types implement the +following traits if allowed to do so by the types of the captures it stores: + +* [`Clone`] +* [`Copy`] +* [`Sync`] +* [`Send`] + +The rules for [`Send`] and [`Sync`] match those for normal struct types, while +[`Clone`] and [`Copy`] behave as if [derived]. For [`Clone`], the order of +cloning of the captured variables is left unspecified. + +Because captures are often by reference, the following general rules arise: + +* A closure is [`Sync`] if all captured variables are [`Sync`]. +* A closure is [`Send`] if all variables captured by non-unique immutable + reference are [`Sync`], and all values captured by unique immutable or mutable + reference, copy, or move are [`Send`]. +* A closure is [`Clone`] or [`Copy`] if it does not capture any values by + unique immutable or mutable reference, and if all values it captures by copy + or move are [`Clone`] or [`Copy`], respectively. + +[`Clone`]: special-types-and-traits.html#clone +[`Copy`]: special-types-and-traits.html#copy +[`FnMut`]: ../std/ops/trait.FnMut.html +[`FnOnce`]: ../std/ops/trait.FnOnce.html +[`Fn`]: ../std/ops/trait.Fn.html +[`Send`]: special-types-and-traits.html#send +[`Sized`]: special-types-and-traits.html#sized +[`Sync`]: special-types-and-traits.html#sync +[closure expression]: expressions/closure-expr.html +[derived]: attributes.html#derive diff --git a/src/types/enum.md b/src/types/enum.md new file mode 100644 index 000000000..e40ca381a --- /dev/null +++ b/src/types/enum.md @@ -0,0 +1,23 @@ +# Enumerated types + +An *enumerated type* is a nominal, heterogeneous disjoint union type, denoted +by the name of an [`enum` item]. [^enumtype] + +An [`enum` item] 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]. + +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]. + +[^enumtype]: The `enum` type is analogous to a `data` constructor declaration in + ML, or a *pick ADT* in Limbo. + +[`enum` item]: items/enumerations.html +[enumeration variant expression]: expressions/enum-variant-expr.html diff --git a/src/types/function-item.md b/src/types/function-item.md new file mode 100644 index 000000000..dee74e48e --- /dev/null +++ b/src/types/function-item.md @@ -0,0 +1,57 @@ +# Function item types + +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 no syntax that directly refers to a function item type, but the +compiler will display the type as something like `fn(u32) -> i32 {fn_name}` 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,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] 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`: + +```rust +# let want_i32 = false; +# fn foo() { } + +// `foo_ptr_1` has function pointer type `fn()` here +let foo_ptr_1: fn() = foo::; + +// ... and so does `foo_ptr_2` - this type-checks. +let foo_ptr_2 = if want_i32 { + foo:: +} else { + foo:: +}; +``` + +All function items implement [`Fn`], [`FnMut`], [`FnOnce`], [`Copy`], +[`Clone`], [`Send`], and [`Sync`]. + +[`Clone`]: special-types-and-traits.html#clone +[`Copy`]: special-types-and-traits.html#copy +[`FnMut`]: ../std/ops/trait.FnMut.html +[`FnOnce`]: ../std/ops/trait.FnOnce.html +[`Fn`]: ../std/ops/trait.Fn.html +[`Send`]: special-types-and-traits.html#send +[`Sync`]: special-types-and-traits.html#sync +[coercion]: type-coercions.html +[function pointers]: types/function-pointer.html diff --git a/src/types/function-pointer.md b/src/types/function-pointer.md new file mode 100644 index 000000000..2df279e66 --- /dev/null +++ b/src/types/function-pointer.md @@ -0,0 +1,55 @@ +# Function pointer types + +> **Syntax**\ +> _BareFunctionType_ :\ +>    [_ForLifetimes_]? [_FunctionQualifiers_] `fn`\ +>       `(` _FunctionParametersMaybeNamedVariadic_? `)` _BareFunctionReturnType_? +> +> _BareFunctionReturnType_:\ +>    `->` [_TypeNoBounds_] +> +> _FunctionParametersMaybeNamedVariadic_ :\ +>    _MaybeNamedFunctionParameters_ | _MaybeNamedFunctionParametersVariadic_ +> +> _MaybeNamedFunctionParameters_ :\ +>    _MaybeNamedParam_ ( `,` _MaybeNamedParam_ )\* `,`? +> +> _MaybeNamedParam_ :\ +>    ( ( [IDENTIFIER] | `_` ) `:` )? [_Type_] +> +> _MaybeNamedFunctionParametersVariadic_ :\ +>    ( _MaybeNamedParam_ `,` )\* _MaybeNamedParam_ `,` `...` + +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] and non-capturing [closures]. + +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. + +Variadic parameters can only be specified with [`extern`] function types with +the `"C"` or `"cdecl"` calling convention. + +An example where `Binop` is defined as a function pointer type: + +```rust +fn add(x: i32, y: i32) -> i32 { + x + y +} + +let mut x = add(5,7); + +type Binop = fn(i32, i32) -> i32; +let bo: Binop = add; +x = bo(5,7); +``` + +[IDENTIFIER]: identifiers.html +[_ForLifetimes_]: items/generics.html#where-clauses +[_FunctionQualifiers_]: items/functions.html +[_TypeNoBounds_]: types.html#type-expressions +[_Type_]: types.html#type-expressions +[`extern`]: items/external-blocks.html +[closures]: types/closure.html +[function items]: types/function-item.html diff --git a/src/types/impl-trait.md b/src/types/impl-trait.md new file mode 100644 index 000000000..db3c2d89f --- /dev/null +++ b/src/types/impl-trait.md @@ -0,0 +1,37 @@ +# Impl trait + +> **Syntax**\ +> _ImplTraitType_ : `impl` [_TypeParamBounds_] +> +> _ImplTraitTypeOneBound_ : `impl` [_TraitBound_] + +## Anonymous type parameters + +> Note: This section is a placeholder for more comprehensive reference +> material. + +> Note: This is often called "impl Trait in argument position". + +Functions can declare an argument to be an anonymous type parameter where the +callee must provide a type that has the bounds declared by the anonymous type +parameter and the function can only use the methods available by the trait +bounds of the anonymous type parameter. + +They are written as `impl` followed by a set of trait bounds. + +## Abstract return types + +> Note: This section is a placeholder for more comprehensive reference +> material. + +> Note: This is often called "impl Trait in return position". + +Functions, except for associated trait functions, can return an abstract +return type. These types stand in for another concrete type where the +use-site may only use the trait methods declared by the trait bounds of the +type. + +They are written as `impl` followed by a set of trait bounds. + +[_TraitBound_]: trait-bounds.html +[_TypeParamBounds_]: trait-bounds.html diff --git a/src/types/never.md b/src/types/never.md new file mode 100644 index 000000000..57096ea83 --- /dev/null +++ b/src/types/never.md @@ -0,0 +1,8 @@ +# Never type + +> **Syntax**\ +> _NeverType_ : `!` + +The never type `!` is a type with no values, representing the result of +computations that never complete. Expressions of type `!` can be coerced into +any other type. diff --git a/src/types/numeric.md b/src/types/numeric.md new file mode 100644 index 000000000..86674af0b --- /dev/null +++ b/src/types/numeric.md @@ -0,0 +1,28 @@ +# Numeric types + +## Machine types + +The machine types are the following: + +* The unsigned word types `u8`, `u16`, `u32`, `u64`, and `u128` with values + drawn from the integer intervals [0, 2^8 - 1], [0, 2^16 - 1], [0, 2^32 - 1], + [0, 2^64 - 1], and [0, 2^128 - 1] respectively. + +* The signed two's complement word types `i8`, `i16`, `i32`, `i64`, and `i128`, + with values drawn from the integer intervals [-(2^7), 2^7 - 1], + [-(2^15), 2^15 - 1], [-(2^31), 2^31 - 1], [-(2^63), 2^63 - 1], and + [-(2^127), 2^127 - 1] respectively. + +* The IEEE 754-2008 "binary32" and "binary64" floating-point types: `f32` and + `f64`, respectively. + +## Machine-dependent integer types + +The `usize` type is an unsigned integer type with the same number of bits as the +platform's pointer type. It can represent every memory address in the process. + +The `isize` type is a signed integer type with the same number of bits as the +platform's pointer type. The theoretical upper bound on object and array size +is the maximum `isize` value. This ensures that `isize` can be used to calculate +differences between pointers into an object or array and can address every byte +within an object along with one byte past the end. diff --git a/src/types/pointer.md b/src/types/pointer.md new file mode 100644 index 000000000..e61f0fa1d --- /dev/null +++ b/src/types/pointer.md @@ -0,0 +1,57 @@ +# Pointer types + +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 (`&`) + +> **Syntax**\ +> _ReferenceType_ :\ +>    `&` [_Lifetime_]? `mut`? [_TypeNoBounds_] + +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] 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] 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`) + +> **Syntax**\ +> _RawPointerType_ :\ +>    `*` ( `mut` | `const` ) [_TypeNoBounds_] + +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], 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] they +also have their addition data compared. + +## Smart Pointers + +The standard library contains additional 'smart pointer' types beyond references +and raw pointers. + +[Interior mutability]: interior-mutability.html +[_Lifetime_]: trait-bounds.html +[_TypeNoBounds_]: types.html#type-expressions +[`unsafe` operation]: unsafety.html +[dynamically sized types]: dynamically-sized-types.html +[temporary value]: expressions.html#temporary-lifetimes diff --git a/src/types/slice.md b/src/types/slice.md new file mode 100644 index 000000000..3a5a05d08 --- /dev/null +++ b/src/types/slice.md @@ -0,0 +1,32 @@ +# Slice types + +> **Syntax**\ +> _SliceType_ :\ +>    `[` [_Type_] `]` + +A slice is a [dynamically sized type] representing a 'view' into a sequence of +elements of type `T`. The slice type is written as `[T]`. + +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: + +```rust +// A heap-allocated array, coerced to a slice +let boxed_array: Box<[i32]> = Box::new([1, 2, 3]); + +// A (shared) slice into an array +let slice: &[i32] = &boxed_array[..]; +``` + +All elements of slices are always initialized, and access to a slice is always +bounds-checked in safe methods and operators. + +[_Type_]: types.html#type-expressions +[dynamically sized type]: dynamically-sized-types.html diff --git a/src/types/struct.md b/src/types/struct.md new file mode 100644 index 000000000..a398d1b91 --- /dev/null +++ b/src/types/struct.md @@ -0,0 +1,28 @@ +# Struct types + +A `struct` *type* is a heterogeneous product of other types, called the +*fields* of the type.[^structtype] + +New instances of a `struct` can be constructed with a [struct expression]. + +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 +have the same memory layout. + +The fields of a `struct` may be qualified by [visibility modifiers], 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] 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. + +[struct expression]: expressions/struct-expr.html +[visibility modifiers]: visibility-and-privacy.html diff --git a/src/types/textual.md b/src/types/textual.md new file mode 100644 index 000000000..e5fe6db7a --- /dev/null +++ b/src/types/textual.md @@ -0,0 +1,16 @@ +# Textual types + +The types `char` and `str` hold textual data. + +A value of type `char` is a [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]` 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 a +[dynamically sized type], it is not a _first-class_ type, but can only be +instantiated through a pointer type, such as `&str`. + +[Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value +[dynamically sized type]: dynamically-sized-types.html diff --git a/src/types/trait-object.md b/src/types/trait-object.md new file mode 100644 index 000000000..eb31a1bbd --- /dev/null +++ b/src/types/trait-object.md @@ -0,0 +1,114 @@ +# Trait objects + +> **Syntax**\ +> _TraitObjectType_ :\ +>    `dyn`? [_TypeParamBounds_] +> +> _TraitObjectTypeOneBound_ :\ +>    `dyn`? [_TraitBound_] + +A *trait object* is an opaque value of another type that implements a set of +traits. The set of traits is made up of an [object safe] *base trait* plus any +number of [auto traits]. + +Trait objects implement the base trait, its auto traits, and any [supertraits] +of the base trait. + +Trait objects are written as the optional keyword `dyn` followed by a set of +trait bounds, but with the following restrictions on the trait bounds. All +traits except the first trait must be auto traits, there may not be more than +one lifetime, and opt-out bounds (e.g. `?sized`) are not allowed. Furthermore, +paths to traits may be parenthesized. + +For example, given a trait `Trait`, the following are all trait objects: + +* `Trait` +* `dyn Trait` +* `dyn Trait + Send` +* `dyn Trait + Send + Sync` +* `dyn Trait + 'static` +* `dyn Trait + Send + 'static` +* `dyn Trait +` +* `dyn 'static + Trait`. +* `dyn (Trait)` + +> **Edition Differences**: In the 2015 edition, if the first bound of the +> trait object is a path that starts with `::`, then the `dyn` will be treated +> as a part of the path. The first path can be put in parenthesis to get +> around this. As such, if you want a trait object with the trait +> `::your_module::Trait`, you should write it as `dyn (::your_module::Trait)`. +> +> Beginning in the 2018 edition, `dyn` is a true keyword and is not allowed in +> paths, so the parentheses are not necessary. + +> Note: For clarity, it is recommended to always use the `dyn` keyword on your +> trait objects unless your codebase supports compiling with Rust 1.26 or lower. + +Two trait object types alias each other if the base traits alias each other and +if the sets of auto traits are the same and the lifetime bounds are the same. +For example, `dyn Trait + Send + UnwindSafe` is the same as +`dyn Trait + Unwindsafe + Send`. + +
+ +***Warning:*** With two trait object types, even when the complete set of traits +is the same, if the base traits differ, the type is different. For example, +`dyn Send + Sync` is a different type from `dyn Sync + Send`. See [issue 33140]. + +
+ +Due to the opaqueness of which concrete type the value is of, trait objects are +[dynamically sized types]. Like all +DSTs, trait objects are used +behind some type of pointer; for example `&dyn SomeTrait` or +`Box`. Each instance of a pointer to a trait object includes: + + - a pointer to an instance of a type `T` that implements `SomeTrait` + - a _virtual method table_, often just called a _vtable_, which contains, for + each method of `SomeTrait` and its [supertraits] that `T` implements, a + pointer to `T`'s implementation (i.e. a function pointer). + +The purpose of trait objects is to permit "late binding" of methods. Calling a +method on a trait object results in virtual dispatch at runtime: that is, a +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. + +An example of a trait object: + +```rust +trait Printable { + fn stringify(&self) -> String; +} + +impl Printable for i32 { + fn stringify(&self) -> String { self.to_string() } +} + +fn print(a: Box) { + println!("{}", a.stringify()); +} + +fn main() { + print(Box::new(10) as Box); +} +``` + +In this example, the trait `Printable` occurs as a trait object in both the +type signature of `print`, and the cast expression in `main`. + +## Trait Object Lifetime Bounds + +Since a trait object can contain references, the lifetimes of those references +need to be expressed as part of the trait object. This lifetime is written as +`Trait + 'a`. There are [defaults] that allow this lifetime to usually be +inferred with a sensible choice. + +[_TraitBound_]: trait-bounds.html +[_TypeParamBounds_]: types.html#type-expressions +[auto traits]: special-types-and-traits.html#auto-traits +[defaults]: lifetime-elision.html#default-trait-object-lifetimes +[dynamically sized types]: dynamically-sized-types.html +[issue 33140]: https://github.com/rust-lang/rust/issues/33140 +[object safe]: items/traits.html#object-safety +[supertraits]: items/traits.html#supertraits diff --git a/src/types/tuple.md b/src/types/tuple.md new file mode 100644 index 000000000..195346b2d --- /dev/null +++ b/src/types/tuple.md @@ -0,0 +1,34 @@ +# Tuple types + +> **Syntax**\ +> _TupleType_ :\ +>       `(` `)`\ +>    | `(` ( [_Type_] `,` )+ [_Type_]? `)` + +A tuple *type* is a heterogeneous product of other types, called the *elements* +of the tuple. It has no nominal name and is instead structurally typed. + +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. + +An example of a tuple type and its use: + +```rust +type Pair<'a> = (i32, &'a str); +let p: Pair<'static> = (10, "ten"); +let (a, b) = p; + +assert_eq!(a, 10); +assert_eq!(b, "ten"); +assert_eq!(p.0, 10); +assert_eq!(p.1, "ten"); +``` + +For historical reasons and convenience, the tuple type with no elements (`()`) +is often called ‘unit’ or ‘the unit type’. + +[_Type_]: types.html#type-expressions diff --git a/src/types/union.md b/src/types/union.md new file mode 100644 index 000000000..68f851549 --- /dev/null +++ b/src/types/union.md @@ -0,0 +1,15 @@ +# Union types + +A *union type* is a nominal, heterogeneous C-like union, denoted by the name of +a [`union` item]. + +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`]. + +The memory layout of a `union` is undefined by default, but the `#[repr(...)]` +attribute can be used to fix a layout. + +[`Copy`]: special-types-and-traits.html#copy +[`union` item]: items/unions.html diff --git a/src/unsafety.md b/src/unsafety.md index 0f4fab9e6..e9bb78652 100644 --- a/src/unsafety.md +++ b/src/unsafety.md @@ -16,5 +16,5 @@ Rust: [`union`]: items/unions.html [mutable static variable]: items/static-items.html#mutable-statics [external static variable]: items/external-blocks.html -[raw pointer]: types.html#pointer-types +[raw pointer]: types/pointer.html [unsafe trait]: items/traits.html#unsafe-traits From 18f141803e0aa92796c2f6b2121da448723c533e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 23 Oct 2018 15:37:55 -0700 Subject: [PATCH 2/3] Minor review edits. --- src/paths.md | 2 +- src/types-redirect.html | 2 +- src/types.md | 5 ++--- src/types/array.md | 6 ++---- src/types/function-pointer.md | 7 ++++--- src/types/numeric.md | 34 +++++++++++++++++++++++----------- 6 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/paths.md b/src/paths.md index d0fe535e8..f363b6399 100644 --- a/src/paths.md +++ b/src/paths.md @@ -185,7 +185,7 @@ fn bar() { ### `Self` -`Self` with a capital "S" is used to refer to the implementing type within +`Self`, with a capital "S", is used to refer to the implementing type within [traits] and [implementations]. `Self` can only be used as the first segment, without a preceding `::`. diff --git a/src/types-redirect.html b/src/types-redirect.html index e1185ffed..9e3899607 100644 --- a/src/types-redirect.html +++ b/src/types-redirect.html @@ -3,7 +3,7 @@ var fragments = { "#boolean-type": "types/boolean.html", "#numeric-types": "types/numeric.html", - "#machine-types": "types/numeric.html#machine-types", + "#machine-types": "types/numeric.html", "#machine-dependent-integer-types": "types/numeric.html#machine-dependent-integer-types", "#textual-types": "types/textual.html", "#never-type": "types/never.html", diff --git a/src/types.md b/src/types.md index 28ebdbd87..076fc22d0 100644 --- a/src/types.md +++ b/src/types.md @@ -15,7 +15,7 @@ The list of types is: * [Boolean] — `true` or `false` * [Numeric] — integer and float * [Textual] — `char` and `str` - * [Never] — `!` — a type with no value + * [Never] — `!` — a type with no values * Sequence types: * [Tuple] * [Array] @@ -35,7 +35,6 @@ The list of types is: * [Trait objects] * [Impl trait] - ## Type expressions > **Syntax**\ @@ -91,7 +90,7 @@ require this disambiguation use the [_TypeNoBounds_] rule instead of ```rust # use std::any::Any; -type T<'a> = &'a(Any + Send); +type T<'a> = &'a (dyn Any + Send); ``` ### Inferred type diff --git a/src/types/array.md b/src/types/array.md index eca0c82be..a091675fe 100644 --- a/src/types/array.md +++ b/src/types/array.md @@ -5,10 +5,8 @@ >    `[` [_Type_] `;` [_Expression_] `]` An array is a fixed-size sequence of `N` elements of type `T`. The array type -is written as `[T; N]`. - -An array can be allocated on either the stack or the heap. The size is an -expression that evaluates to a [`usize`]. +is written as `[T; N]`. The size is an expression that evaluates to a +[`usize`]. Examples: diff --git a/src/types/function-pointer.md b/src/types/function-pointer.md index 2df279e66..be0302cb2 100644 --- a/src/types/function-pointer.md +++ b/src/types/function-pointer.md @@ -24,9 +24,8 @@ 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] and non-capturing [closures]. -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. +The `unsafe` qualifier indicates that the type's value is an [unsafe +function], and the `extern` qualifier indicates it is an [extern function]. Variadic parameters can only be specified with [`extern`] function types with the `"C"` or `"cdecl"` calling convention. @@ -52,4 +51,6 @@ x = bo(5,7); [_Type_]: types.html#type-expressions [`extern`]: items/external-blocks.html [closures]: types/closure.html +[extern function]: items/functions.html#extern-functions [function items]: types/function-item.html +[unsafe function]: unsafe-functions.html diff --git a/src/types/numeric.md b/src/types/numeric.md index 86674af0b..4d81be13b 100644 --- a/src/types/numeric.md +++ b/src/types/numeric.md @@ -1,20 +1,32 @@ # Numeric types -## Machine types +## Integer types -The machine types are the following: +The unsigned integer types consist of: -* The unsigned word types `u8`, `u16`, `u32`, `u64`, and `u128` with values - drawn from the integer intervals [0, 2^8 - 1], [0, 2^16 - 1], [0, 2^32 - 1], - [0, 2^64 - 1], and [0, 2^128 - 1] respectively. +Type | Minimum | Maximum +-------|---------|------------------- +`u8` | 0 | 28-1 +`u16` | 0 | 216-1 +`u32` | 0 | 232-1 +`u64` | 0 | 264-1 +`u128` | 0 | 2128-1 -* The signed two's complement word types `i8`, `i16`, `i32`, `i64`, and `i128`, - with values drawn from the integer intervals [-(2^7), 2^7 - 1], - [-(2^15), 2^15 - 1], [-(2^31), 2^31 - 1], [-(2^63), 2^63 - 1], and - [-(2^127), 2^127 - 1] respectively. +The signed two's complement integer types consist of: -* The IEEE 754-2008 "binary32" and "binary64" floating-point types: `f32` and - `f64`, respectively. +Type | Minimum | Maximum +-------|--------------------|------------------- +`i8` | -(27) | 27-1 +`i16` | -(215) | 215-1 +`i32` | -(231) | 231-1 +`i64` | -(263) | 263-1 +`i128` | -(2127) | 2127-1 + + +## Floating-point types + +The IEEE 754-2008 "binary32" and "binary64" floating-point types are `f32` and +`f64`, respectively. ## Machine-dependent integer types From eb02dd5194a747277bfa46b0185d1f5c248f177b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 4 Nov 2018 18:16:57 -0800 Subject: [PATCH 3/3] Move Inferred Types and Type Parameters to their own pages. --- src/SUMMARY.md | 2 ++ src/keywords.md | 2 +- src/special-types-and-traits.md | 2 +- src/tokens.md | 2 +- src/types-redirect.html | 4 ++- src/types.md | 47 +++------------------------------ src/types/inferred.md | 18 +++++++++++++ src/types/parameters.md | 19 +++++++++++++ 8 files changed, 48 insertions(+), 48 deletions(-) create mode 100644 src/types/inferred.md create mode 100644 src/types/parameters.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 2022cbf06..45edc3040 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -83,6 +83,8 @@ - [Function pointer types](types/function-pointer.md) - [Trait object types](types/trait-object.md) - [Impl trait type](types/impl-trait.md) + - [Type parameters](types/parameters.md) + - [Inferred type](types/inferred.md) - [Dynamically Sized Types](dynamically-sized-types.md) - [Type layout](type-layout.md) - [Interior mutability](interior-mutability.md) diff --git a/src/keywords.md b/src/keywords.md index b732dd3b9..a0dc33dfa 100644 --- a/src/keywords.md +++ b/src/keywords.md @@ -118,7 +118,7 @@ is possible to declare a variable or method with the name `union`. [items]: items.html [Variables]: variables.html -[Type parameters]: types.html#type-parameters +[Type parameters]: types/parameters.html [loop labels]: expressions/loop-expr.html#loop-labels [Macros]: macros.html [attributes]: attributes.html diff --git a/src/special-types-and-traits.md b/src/special-types-and-traits.md index f78686fbe..cefdc2ed2 100644 --- a/src/special-types-and-traits.md +++ b/src/special-types-and-traits.md @@ -162,6 +162,6 @@ compiler, not by [implementation items]. [the standard library]: ../std/index.html [trait object]: types/trait-object.html [Tuples]: types/tuple.html -[Type parameters]: types.html#type-parameters +[Type parameters]: types/parameters.html [variance]: subtyping.html#variance [`!`]: types/never.html diff --git a/src/tokens.md b/src/tokens.md index 13ef1e458..2f772dfcf 100644 --- a/src/tokens.md +++ b/src/tokens.md @@ -576,7 +576,7 @@ them are referred to as "token trees" in [macros]. The three types of brackets | `(` `)` | Parentheses | -[Inferred types]: types.html#inferred-type +[Inferred types]: types/inferred.html [Operator expressions]: expressions/operator-expr.html [Range patterns]: patterns.html#range-patterns [Reference patterns]: patterns.html#reference-patterns diff --git a/src/types-redirect.html b/src/types-redirect.html index 9e3899607..26d5410a7 100644 --- a/src/types-redirect.html +++ b/src/types-redirect.html @@ -29,7 +29,9 @@ "#impl-trait": "types/impl-trait.html", "#anonymous-type-parameters": "types/impl-trait.html#anonymous-type-parameters", "#abstract-return-types": "types/impl-trait.html#abstract-return-types", - "#self-types": "paths.html#self-1" + "#self-types": "paths.html#self-1", + "#inferred-type": "types/inferred.html", + "#type-parameters": "types/parameters.html", }; var target = fragments[window.location.hash]; if (target) { diff --git a/src/types.md b/src/types.md index 076fc22d0..3e44d0159 100644 --- a/src/types.md +++ b/src/types.md @@ -75,7 +75,6 @@ for referring to a type. It may refer to: * The [never] type. * [Macros] which expand to a type expression. - ### Parenthesized types > _ParenthesizedType_ :\ @@ -93,46 +92,6 @@ require this disambiguation use the [_TypeNoBounds_] rule instead of type T<'a> = &'a (dyn Any + Send); ``` -### Inferred type -> **Syntax**\ -> _InferredType_ : `_` - -The inferred type asks the compiler to infer the type if possible based on the -surrounding information available. It cannot be used in item signatures. It is -often used in generic arguments: - -```rust -let x: Vec<_> = (0..10).collect(); -``` - - - - -### Type parameters - -Within the body of an item that has type parameter declarations, the names of -its type parameters are types: - -```rust -fn to_vec(xs: &[A]) -> Vec
{ - if xs.is_empty() { - return vec![]; - } - let first: A = xs[0].clone(); - let mut rest: Vec = to_vec(&xs[1..]); - rest.insert(0, first); - rest -} -``` - -Here, `first` has type `A`, referring to `to_vec`'s `A` type parameter; and -`rest` has type `Vec`, a vector with element type `A`. - - ## Recursive types Nominal types — [structs], [enumerations] and [unions] — may be @@ -164,7 +123,7 @@ let a: List = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil)))); [_BareFunctionType_]: types/function-pointer.html [_ImplTraitTypeOneBound_]: types/impl-trait.html [_ImplTraitType_]: types/impl-trait.html -[_InferredType_]: types.html#inferred-type +[_InferredType_]: types/inferred.html [_MacroInvocation_]: macros.html#macro-invocation [_NeverType_]: types/never.html [_ParenthesizedType_]: types.html#parenthesized-types @@ -202,7 +161,7 @@ let a: List = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil)))); [arrays]: types/array.html [enumerations]: types/enum.html [function pointer]: types/function-pointer.html -[inferred type]: types.html#inferred-type +[inferred type]: types/inferred.html [item]: items.html [never]: types/never.html [pointer types]: types/pointer.html @@ -215,5 +174,5 @@ let a: List = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil)))); [type alias]: items/type-aliases.html [type aliases]: items/type-aliases.html [type boundaries]: trait-bounds.html -[type parameters]: #type-parameters +[type parameters]: types/parameters.html [unions]: types/union.html diff --git a/src/types/inferred.md b/src/types/inferred.md new file mode 100644 index 000000000..0100758b2 --- /dev/null +++ b/src/types/inferred.md @@ -0,0 +1,18 @@ +# Inferred type + +> **Syntax**\ +> _InferredType_ : `_` + +The inferred type asks the compiler to infer the type if possible based on the +surrounding information available. It cannot be used in item signatures. It is +often used in generic arguments: + +```rust +let x: Vec<_> = (0..10).collect(); +``` + + diff --git a/src/types/parameters.md b/src/types/parameters.md new file mode 100644 index 000000000..7b9e7e64e --- /dev/null +++ b/src/types/parameters.md @@ -0,0 +1,19 @@ +# Type parameters + +Within the body of an item that has type parameter declarations, the names of +its type parameters are types: + +```rust +fn to_vec(xs: &[A]) -> Vec { + if xs.is_empty() { + return vec![]; + } + let first: A = xs[0].clone(); + let mut rest: Vec = to_vec(&xs[1..]); + rest.insert(0, first); + rest +} +``` + +Here, `first` has type `A`, referring to `to_vec`'s `A` type parameter; and +`rest` has type `Vec`, a vector with element type `A`.