diff --git a/src/SUMMARY.md b/src/SUMMARY.md
index fb0e6574d..bd9cb9ca7 100644
--- a/src/SUMMARY.md
+++ b/src/SUMMARY.md
@@ -35,7 +35,7 @@
- [Traits](items/traits.md)
- [Implementations](items/implementations.md)
- [External blocks](items/external-blocks.md)
- - [Type and lifetime parameters](items/generics.md)
+ - [Generic parameters](items/generics.md)
- [Associated Items](items/associated-items.md)
- [Visibility and Privacy](visibility-and-privacy.md)
diff --git a/src/const_eval.md b/src/const_eval.md
index b3d087f32..159f0a768 100644
--- a/src/const_eval.md
+++ b/src/const_eval.md
@@ -20,6 +20,7 @@ also constant expressions and do not cause any [`Drop::drop`][destructors] calls
to be run.
* [Literals].
+* [Const parameters].
* [Paths] to [functions] and [constants].
Recursively defining constants is not allowed.
* Paths to [statics]. These are only allowed within the initializer of a static.
@@ -112,6 +113,7 @@ Conversely, the following are possible in a const function, but not in a const c
[comparison]: expressions/operator-expr.md#comparison-operators
[const functions]: items/functions.md#const-functions
[constants]: items/constant-items.md
+[Const parameters]: items/generics.md
[dereference operator]: expressions/operator-expr.md#the-dereference-operator
[destructors]: destructors.md
[enum discriminants]: items/enumerations.md#custom-discriminant-values-for-fieldless-enumerations
diff --git a/src/items/generics.md b/src/items/generics.md
index ba35e64d2..abb50b47f 100644
--- a/src/items/generics.md
+++ b/src/items/generics.md
@@ -1,4 +1,4 @@
-# Type and Lifetime Parameters
+# Generic parameters
> **Syntax**\
> _Generics_ :\
@@ -6,7 +6,8 @@
>
> _GenericParams_ :\
> _LifetimeParams_\
-> | ( _LifetimeParam_ `,` )\* _TypeParams_
+> | ( _LifetimeParam_ `,` )\* _TypeParams_\
+> | ( _LifetimeParam_ `,` )\* ( _TypeParam_ `,` )\* _ConstParams_
>
> _LifetimeParams_ :\
> ( _LifetimeParam_ `,` )\* _LifetimeParam_?
@@ -18,20 +19,55 @@
> ( _TypeParam_ `,` )\* _TypeParam_?
>
> _TypeParam_ :\
-> [_OuterAttribute_]? [IDENTIFIER] ( `:` [_TypeParamBounds_]? )? ( `=` [_Type_] )?
+> [_OuterAttribute_]? [IDENTIFIER]( `:` [_TypeParamBounds_]? )? ( `=` [_Type_] )?
+>
+> _ConstParams_:\
+> ( _ConstParam_ `,` )\* _ConstParam_?
+>
+> _ConstParam_:\
+> [_OuterAttribute_]? `const` [IDENTIFIER] `:` [_Type_]
Functions, type aliases, structs, enumerations, unions, traits, and
-implementations may be *parameterized* by types and lifetimes. These parameters
-are listed in angle brackets (`<...>`),
+implementations may be *parameterized* by types, constants, and lifetimes. These
+parameters are listed in angle brackets (`<...>`),
usually immediately after the name of the item and before its definition. For
implementations, which don't have a name, they come directly after `impl`.
-Lifetime parameters must be declared before type parameters. Some examples of
-items with type and lifetime parameters:
+The order of generic parameters is restricted to lifetime parameters, then type parameters, and then const parameters.
+
+Some examples of items with type, const, and lifetime parameters:
```rust
fn foo<'a, T>() {}
trait A {}
struct Ref<'a, T> where T: 'a { r: &'a T }
+struct InnerArray([T; N]);
+```
+
+The only allowed types of const parameters are `u8`, `u16`, `u32`, `u64`, `u128`, `usize`
+`i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `char` and `bool`.
+
+Const parameters may only be be used as standalone arguments inside
+of [types] and [repeat expressions] but may be freely used elsewhere:
+
+```rust,compile_fail
+// ok: standalone argument
+fn foo() -> [u8; N] { todo!() }
+
+// ERROR: generic const operation
+fn bar() -> [u8; N + 1] { todo!() }
+```
+
+Unlike type and lifetime parameters, const parameters of types can be used without
+being mentioned inside of a parameterized type:
+
+```rust,compile_fail
+// ok
+struct Foo;
+enum Bar { A, B }
+
+// ERROR: unused parameter
+struct Baz;
+struct Biz<'a>;
```
[References], [raw pointers], [arrays], [slices][arrays], [tuples], and
@@ -55,7 +91,7 @@ referred to with path syntax.
> _ForLifetimes_? [_Type_] `:` [_TypeParamBounds_]?
>
> _ForLifetimes_ :\
-> `for` `<` [_LifetimeParams_](#type-and-lifetime-parameters) `>`
+> `for` `<` [_LifetimeParams_](#generic-parameters) `>`
*Where clauses* provide another way to specify bounds on type and lifetime
parameters as well as a way to specify bounds on types that aren't type
@@ -65,7 +101,7 @@ Bounds that don't use the item's parameters or higher-ranked lifetimes are
checked when the item is defined. It is an error for such a bound to be false.
[`Copy`], [`Clone`], and [`Sized`] bounds are also checked for certain generic
-types when defining the item. It is an error to have `Copy` or `Clone`as a
+types when defining the item. It is an error to have `Copy` or `Clone` as a
bound on a mutable reference, [trait object] or [slice][arrays] or `Sized` as a
bound on a trait object or slice.
@@ -112,12 +148,15 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
[_TypeParamBounds_]: ../trait-bounds.md
[arrays]: ../types/array.md
+[const contexts]: ../const_eval.md#const-context
[function pointers]: ../types/function-pointer.md
-[references]: ../types/pointer.md#shared-references-
[raw pointers]: ../types/pointer.md#raw-pointers-const-and-mut
+[references]: ../types/pointer.md#shared-references-
+[repeat expressions]: ../expressions/array-expr.md
[`Clone`]: ../special-types-and-traits.md#clone
[`Copy`]: ../special-types-and-traits.md#copy
[`Sized`]: ../special-types-and-traits.md#sized
[tuples]: ../types/tuple.md
[trait object]: ../types/trait-object.md
+[types]: ../types.md
[attributes]: ../attributes.md
diff --git a/src/paths.md b/src/paths.md
index 821d883d1..47a14ee91 100644
--- a/src/paths.md
+++ b/src/paths.md
@@ -52,11 +52,16 @@ mod m {
> `<` `>`\
> | `<` _GenericArgsLifetimes_ `,`? `>`\
> | `<` _GenericArgsTypes_ `,`? `>`\
+> | `<` _GenericArgsConsts_ `,`? `>`\
> | `<` _GenericArgsBindings_ `,`? `>`\
-> | `<` _GenericArgsTypes_ `,` _GenericArgsBindings_ `,`? `>`\
> | `<` _GenericArgsLifetimes_ `,` _GenericArgsTypes_ `,`? `>`\
+> | `<` _GenericArgsLifetimes_ `,` _GenericArgsConsts_ `,`? `>`\
> | `<` _GenericArgsLifetimes_ `,` _GenericArgsBindings_ `,`? `>`\
-> | `<` _GenericArgsLifetimes_ `,` _GenericArgsTypes_ `,` _GenericArgsBindings_ `,`? `>`
+> | `<` _GenericArgsLifetimes_ `,` _GenericArgsTypes_ `,` _GenericArgsConsts_ `,`? `>`\
+> | `<` _GenericArgsLifetimes_ `,` _GenericArgsTypes_ `,` _GenericArgsBindings_ `,`? `>`\
+> | `<` _GenericArgsLifetimes_ `,` _GenericArgsConsts_ `,` _GenericArgsBindings_ `,`? `>`\
+> | `<` _GenericArgsTypes_ `,` _GenericArgsConsts_ `,` _GenericArgsBindings_ `,`? `>`\
+> | `<` _GenericArgsLifetimes_ `,` _GenericArgsTypes_ `,` _GenericArgsConsts_ `,` _GenericArgsBindings_ `,`? `>`
>
> _GenericArgsLifetimes_ :\
> [_Lifetime_] (`,` [_Lifetime_])\*
@@ -64,6 +69,15 @@ mod m {
> _GenericArgsTypes_ :\
> [_Type_] (`,` [_Type_])\*
>
+> _GenericArgsConsts_ :\
+> _GenericArgsConst_ (`,` _GenericArgsConst_)\*
+>
+> _GenericArgsConst_ :\
+> [_BlockExpression_]\
+> | [_LiteralExpression_]\
+> | `-` [_LiteralExpression_]\
+> | [_SimplePathSegment_]
+>
> _GenericArgsBindings_ :\
> _GenericArgsBinding_ (`,` _GenericArgsBinding_)\*
>
@@ -81,6 +95,9 @@ ambiguity with the less-than operator. This is colloquially known as "turbofish"
Vec::::with_capacity(1024);
```
+Const arguments must be surrounded by braces unless they are a
+[literal] or a single segment path.
+
## Qualified paths
> **Syntax**\
@@ -364,9 +381,14 @@ mod without { // ::without
# fn main() {}
```
+[_BlockExpression_]: expressions/block-expr.md
+[_Expression_]: expressions.md
[_GenericArgs_]: #paths-in-expressions
[_Lifetime_]: trait-bounds.md
+[_LiteralExpression_]: expressions/literal-expr.md
+[_SimplePathSegment_]: #simple-paths
[_Type_]: types.md#type-expressions
+[literal]: expressions/literal-expr.md
[item]: items.md
[variable]: variables.md
[implementations]: items/implementations.md