Skip to content

Commit 6a5a823

Browse files
Merge pull request #433 from ehuss/grammar-types
Grammar: types
2 parents 49d6c3c + 4c862cc commit 6a5a823

File tree

2 files changed

+148
-6
lines changed

2 files changed

+148
-6
lines changed

src/tokens.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ usages and meanings are defined in the linked pages.
548548
| `>=` | Ge | [Greater than or equal to][comparison], [Generics]
549549
| `<=` | Le | [Less than or equal to][comparison]
550550
| `@` | At | [Subpattern binding]
551-
| `_` | Underscore | [Wildcard patterns], Inferred types
551+
| `_` | Underscore | [Wildcard patterns], [Inferred types]
552552
| `.` | Dot | [Field access][field], [Tuple index]
553553
| `..` | DotDot | [Range][range], [Struct expressions], [Patterns]
554554
| `...` | DotDotDot | [Variadic functions][extern], [Range patterns]
@@ -576,6 +576,7 @@ them are referred to as "token trees" in [macros]. The three types of brackets
576576
| `(` `)` | Parentheses |
577577

578578

579+
[Inferred types]: types.html#inferred-type
579580
[Operator expressions]: expressions/operator-expr.html
580581
[Range patterns]: patterns.html#range-patterns
581582
[Reference patterns]: patterns.html#reference-patterns

src/types.md

+146-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# Types
22

3+
> **<sup>Syntax</sup>**\
4+
> _Type_ :\
5+
> &nbsp;&nbsp; &nbsp;&nbsp; _TypeNoBounds_\
6+
> &nbsp;&nbsp; | [_ImplTraitType_]\
7+
> &nbsp;&nbsp; | [_TraitObjectType_]
8+
>
9+
> _TypeNoBounds_ :\
10+
> &nbsp;&nbsp; &nbsp;&nbsp; [_ParenthesizedType_]\
11+
> &nbsp;&nbsp; | [_ImplTraitTypeOneBound_]\
12+
> &nbsp;&nbsp; | [_TraitObjectTypeOneBound_]\
13+
> &nbsp;&nbsp; | [_TypePath_]\
14+
> &nbsp;&nbsp; | [_TupleType_]\
15+
> &nbsp;&nbsp; | [_NeverType_]\
16+
> &nbsp;&nbsp; | [_RawPointerType_]\
17+
> &nbsp;&nbsp; | [_ReferenceType_]\
18+
> &nbsp;&nbsp; | [_ArrayType_]\
19+
> &nbsp;&nbsp; | [_SliceType_]\
20+
> &nbsp;&nbsp; | [_InferredType_]\
21+
> &nbsp;&nbsp; | [_QualifiedPathInType_]\
22+
> &nbsp;&nbsp; | [_BareFunctionType_]
23+
324
Every variable, item and value in a Rust program has a type. The _type_ of a
425
*value* defines the interpretation of the memory holding it.
526

@@ -107,12 +128,20 @@ instantiated through a pointer type, such as `&str`.
107128

108129
## Never type
109130

131+
> **<sup>Syntax</sup>**\
132+
> _NeverType_ : `!`
133+
110134
The never type `!` is a type with no values, representing the result of
111135
computations that never complete. Expressions of type `!` can be coerced into
112136
any other type.
113137

114138
## Tuple types
115139

140+
> **<sup>Syntax</sup>**\
141+
> _TupleType_ :\
142+
> &nbsp;&nbsp; &nbsp;&nbsp; `(` `)`\
143+
> &nbsp;&nbsp; | `(` ( [_Type_] `,` )<sup>+</sup> [_Type_]<sup>?</sup> `)`
144+
116145
A tuple *type* is a heterogeneous product of other types, called the *elements*
117146
of the tuple. It has no nominal name and is instead structurally typed.
118147

@@ -139,15 +168,41 @@ assert_eq!(p.1, "ten");
139168
For historical reasons and convenience, the tuple type with no elements (`()`)
140169
is often called ‘unit’ or ‘the unit type’.
141170

171+
## Parenthesized types
172+
173+
> _ParenthesizedType_ :\
174+
> &nbsp;&nbsp; `(` [_Type_] `)`
175+
176+
In some situations the combination of types may be ambiguous. Use parentheses
177+
around a type to avoid ambiguity. For example, the `+` operator for [type
178+
boundaries] within a [reference type][_ReferenceType_] is unclear where the
179+
boundary applies, so the use of parentheses is required. Grammar rules that
180+
require this disambiguation use the [_TypeNoBounds_] rule instead of
181+
[_Type_].
182+
183+
184+
```rust
185+
# use std::any::Any;
186+
type T<'a> = &'a(Any + Send);
187+
```
188+
142189
## Array, and Slice types
143190

144-
Rust has two different types for a list of items:
191+
> **<sup>Syntax</sup>**\
192+
> _ArrayType_ :\
193+
> &nbsp;&nbsp; `[` [_Type_] `;` [_Expression_] `]`
194+
>
195+
> _SliceType_ :\
196+
> &nbsp;&nbsp; `[` [_Type_] `]`
197+
198+
Rust has two different types for a list of items of the same type:
145199

146200
* `[T; N]`, an 'array'
147201
* `[T]`, a 'slice'
148202

149203
An array has a fixed size, and can be allocated on either the stack or the
150-
heap.
204+
heap. The size is an expression that evaluates to a
205+
[`usize`](#machine-dependent-integer-types).
151206

152207
A slice is a [dynamically sized type] representing a 'view' into an array. To
153208
use a slice type it generally has to be used behind a pointer for example as
@@ -276,6 +331,10 @@ copied, stored into data structs, and returned from functions.
276331

277332
### Shared references (`&`)
278333

334+
> **<sup>Syntax</sup>**\
335+
> _ReferenceType_ :\
336+
> &nbsp;&nbsp; `&` [_Lifetime_]<sup>?</sup> `mut`<sup>?</sup> [_TypeNoBounds_]
337+
279338
These point to memory _owned by some other value_. When a shared reference to a
280339
value is created it prevents direct mutation of the value. [Interior
281340
mutability](interior-mutability.html) provides an exception for this in certain
@@ -295,6 +354,10 @@ borrowed) is the only way to access the value it points to, so is not `Copy`.
295354

296355
### Raw pointers (`*const` and `*mut`)
297356

357+
> **<sup>Syntax</sup>**\
358+
> _RawPointerType_ :\
359+
> &nbsp;&nbsp; `*` ( `mut` | `const` ) [_TypeNoBounds_]
360+
298361
Raw pointers are pointers without safety or liveness guarantees. Raw pointers
299362
are written as `*const T` or `*mut T`, for example `*const i32` means a raw
300363
pointer to a 32-bit integer. Copying or dropping a raw pointer has no effect on
@@ -366,6 +429,26 @@ All function items implement [`Fn`], [`FnMut`], [`FnOnce`], [`Copy`],
366429

367430
## Function pointer types
368431

432+
> **<sup>Syntax</sup>**\
433+
> _BareFunctionType_ :\
434+
> &nbsp;&nbsp; [_ForLifetimes_]<sup>?</sup> [_FunctionFront_] `fn`\
435+
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _FunctionParametersMaybeNamedVariadic_<sup>?</sup> `)` _BareFunctionReturnType_<sup>?</sup>
436+
>
437+
> _BareFunctionReturnType_:\
438+
> &nbsp;&nbsp; `->` [_TypeNoBounds_]
439+
>
440+
> _FunctionParametersMaybeNamedVariadic_ :\
441+
> &nbsp;&nbsp; _MaybeNamedFunctionParameters_ | _MaybeNamedFunctionParametersVariadic_
442+
>
443+
> _MaybeNamedFunctionParameters_ :\
444+
> &nbsp;&nbsp; _MaybeNamedParam_ ( `,` _MaybeNamedParam_ )<sup>\*</sup> `,`<sup>?</sup>
445+
>
446+
> _MaybeNamedParam_ :\
447+
> &nbsp;&nbsp; ( ( [IDENTIFIER] | `_` ) `:` )<sup>?</sup> [_Type_]
448+
>
449+
> _MaybeNamedFunctionParametersVariadic_ :\
450+
> &nbsp;&nbsp; ( _MaybeNamedParam_ `,` )<sup>\*</sup> _MaybeNamedParam_ `,` `...`
451+
369452
Function pointer types, written using the `fn` keyword, refer to a function
370453
whose identity is not necessarily known at compile-time. They can be created
371454
via a coercion from both [function items](#function-item-types) and
@@ -375,6 +458,9 @@ A function pointer type consists of a possibly-empty set of function-type
375458
modifiers (such as `unsafe` or `extern`), a sequence of input types and an
376459
output type.
377460

461+
Variadic parameters can only be specified with [`extern`] function types with
462+
the `"C"` or `"cdecl"` calling convention.
463+
378464
An example where `Binop` is defined as a function pointer type:
379465

380466
```rust
@@ -560,7 +646,10 @@ Because captures are often by reference, the following general rules arise:
560646

561647
> **<sup>Syntax</sup>**\
562648
> _TraitObjectType_ :\
563-
> &nbsp;&nbsp; `dyn`<sup>?</sup> _TypeParamBounds_
649+
> &nbsp;&nbsp; `dyn`<sup>?</sup> [_TypeParamBounds_]
650+
>
651+
> _TraitObjectTypeOneBound_ :\
652+
> &nbsp;&nbsp; `dyn`<sup>?</sup> [_TraitBound_]
564653
565654
A *trait object* is an opaque value of another type that implements a set of
566655
traits. The set of traits is made up of an [object safe] *base trait* plus any
@@ -658,6 +747,24 @@ inferred with a sensible choice.
658747

659748
[defaults]: lifetime-elision.html#default-trait-object-lifetimes
660749

750+
## Inferred type
751+
> **<sup>Syntax</sup>**\
752+
> _InferredType_ : `_`
753+
754+
The inferred type asks the compiler to infer the type if possible based on the
755+
surrounding information available. It cannot be used in item signatures. It is
756+
often used in generic arguments:
757+
758+
```rust
759+
let x: Vec<_> = (0..10).collect();
760+
```
761+
762+
<!--
763+
What else should be said here?
764+
The only documentation I am aware of is https://rust-lang-nursery.github.io/rustc-guide/type-inference.html
765+
There should be a broader discussion of type inference somewhere.
766+
-->
767+
661768
## Type parameters
662769

663770
Within the body of an item that has type parameter declarations, the names of
@@ -678,7 +785,14 @@ fn to_vec<A: Clone>(xs: &[A]) -> Vec<A> {
678785
Here, `first` has type `A`, referring to `to_vec`'s `A` type parameter; and
679786
`rest` has type `Vec<A>`, a vector with element type `A`.
680787

681-
## Anonymous type parameters
788+
## Impl trait
789+
790+
> **<sup>Syntax</sup>**\
791+
> _ImplTraitType_ : `impl` [_TypeParamBounds_]
792+
>
793+
> _ImplTraitTypeOneBound_ : `impl` [_TraitBound_]
794+
795+
### Anonymous type parameters
682796

683797
> Note: This section is a placeholder for more comprehensive reference
684798
> material.
@@ -692,7 +806,7 @@ bounds of the anonymous type parameter.
692806

693807
They are written as `impl` followed by a set of trait bounds.
694808

695-
## Abstract return types
809+
### Abstract return types
696810

697811
> Note: This section is a placeholder for more comprehensive reference
698812
> material.
@@ -740,6 +854,31 @@ impl Printable for String {
740854

741855
> Note: The notation `&self` is a shorthand for `self: &Self`.
742856
857+
[IDENTIFIER]: identifiers.html
858+
[_ArrayType_]: #array-and-slice-types
859+
[_BareFunctionType_]: #function-pointer-types
860+
[_Expression_]: expressions.html
861+
[_ForLifetimes_]: items/generics.html#where-clauses
862+
[_FunctionFront_]: items/functions.html
863+
[_FunctionParametersMaybeNamed_]: items/functions.html
864+
[_ImplTraitTypeOneBound_]: #impl-trait
865+
[_ImplTraitType_]: #impl-trait
866+
[_InferredType_]: #inferred-type
867+
[_Lifetime_]: trait-bounds.html
868+
[_NeverType_]: #never-type
869+
[_ParenthesizedType_]: #parenthesized-types
870+
[_QualifiedPathInType_]: paths.html#qualified-paths
871+
[_RawPointerType_]: #raw-pointers-const-and-mut
872+
[_ReferenceType_]: #shared-references-
873+
[_SliceType_]: #array-and-slice-types
874+
[_TraitBound_]: trait-bounds.html
875+
[_TraitObjectTypeOneBound_]: #trait-objects
876+
[_TraitObjectType_]: #trait-objects
877+
[_TupleType_]: #tuple-types
878+
[_TypeNoBounds_]: #types
879+
[_TypeParamBounds_]: trait-bounds.html
880+
[_TypePath_]: paths.html#paths-in-types
881+
[_Type_]: #types
743882
[`Fn`]: ../std/ops/trait.Fn.html
744883
[`FnMut`]: ../std/ops/trait.FnMut.html
745884
[`FnOnce`]: ../std/ops/trait.FnOnce.html
@@ -748,6 +887,7 @@ impl Printable for String {
748887
[`Send`]: special-types-and-traits.html#send
749888
[`Sync`]: special-types-and-traits.html#sync
750889
[`Sized`]: special-types-and-traits.html#sized
890+
[`extern`]: items/external-blocks.html
751891
[derive]: attributes.html#derive
752892
[`Vec<T>`]: ../std/vec/struct.Vec.html
753893
[dynamically sized type]: dynamically-sized-types.html
@@ -759,3 +899,4 @@ impl Printable for String {
759899
[issue 47010]: https://github.com/rust-lang/rust/issues/47010
760900
[issue 33140]: https://github.com/rust-lang/rust/issues/33140
761901
[supertraits]: items/traits.html#supertraits
902+
[type boundaries]: trait-bounds.html

0 commit comments

Comments
 (0)