Skip to content

Commit 3250ddf

Browse files
committed
Move examples into example blocks
1 parent 574a6bc commit 3250ddf

1 file changed

Lines changed: 99 additions & 93 deletions

File tree

src/types/generics/index.md

Lines changed: 99 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -364,62 +364,64 @@ Const parameters can be used anywhere a [const item] can be used, with the excep
364364
4. As a parameter to any type used in the body of any functions in the item.
365365
5. As a part of the type of any fields in the item.
366366
367-
```rust
368-
// Examples where const generic parameters can be used.
369-
370-
// Used in the signature of the item itself.
371-
fn foo<const N: usize>(arr: [i32; N]) {
372-
// Used as a type within a function body.
373-
let x: [i32; N];
374-
// Used as an expression.
375-
println!("{}", N * 2);
376-
}
377-
378-
// Used as a field of a struct.
379-
struct Foo<const N: usize>([i32; N]);
380-
381-
impl<const N: usize> Foo<N> {
382-
// Used as an associated constant.
383-
const CONST: usize = N * 4;
384-
}
385-
386-
trait Trait {
387-
type Output;
388-
}
389-
390-
impl<const N: usize> Trait for Foo<N> {
391-
// Used as an associated type.
392-
type Output = [i32; N];
393-
}
394-
```
395-
396-
```rust,compile_fail
397-
// Examples where const generic parameters cannot be used.
398-
fn foo<const N: usize>() {
399-
// Cannot use in item definitions within a function body.
400-
const BAD_CONST: [usize; N] = [1; N];
401-
static BAD_STATIC: [usize; N] = [1; N];
402-
fn inner(bad_arg: [usize; N]) {
403-
let bad_value = N * 2;
404-
}
405-
type BadAlias = [usize; N];
406-
struct BadStruct([usize; N]);
407-
}
408-
```
367+
> [!EXAMPLE]
368+
> ```rust
369+
> // Examples where const generic parameters can be used.
370+
>
371+
> // Used in the signature of the item itself.
372+
> fn foo<const N: usize>(arr: [i32; N]) {
373+
> // Used as a type within a function body.
374+
> let x: [i32; N];
375+
> // Used as an expression.
376+
> println!("{}", N * 2);
377+
> }
378+
>
379+
> // Used as a field of a struct.
380+
> struct Foo<const N: usize>([i32; N]);
381+
>
382+
> impl<const N: usize> Foo<N> {
383+
> // Used as an associated constant.
384+
> const CONST: usize = N * 4;
385+
> }
386+
>
387+
> trait Trait {
388+
> type Output;
389+
> }
390+
>
391+
> impl<const N: usize> Trait for Foo<N> {
392+
> // Used as an associated type.
393+
> type Output = [i32; N];
394+
> }
395+
> ```
396+
>
397+
> ```rust,compile_fail
398+
> // Examples where const generic parameters cannot be used.
399+
> fn foo<const N: usize>() {
400+
> // Cannot use in item definitions within a function body.
401+
> const BAD_CONST: [usize; N] = [1; N];
402+
> static BAD_STATIC: [usize; N] = [1; N];
403+
> fn inner(bad_arg: [usize; N]) {
404+
> let bad_value = N * 2;
405+
> }
406+
> type BadAlias = [usize; N];
407+
> struct BadStruct([usize; N]);
408+
> }
409+
> ```
409410
410411
r[generics.const.standalone]
411412
As a further restriction, const parameters may only appear as a standalone argument inside of a [type] or [array repeat expression]. In those contexts, they may only be used as a single segment [path expression], possibly inside a [block] (such as `N` or `{N}`). That is, they cannot be combined with other expressions.
412413
413-
```rust,compile_fail
414-
// Examples where const parameters may not be used.
415-
416-
// Not allowed to combine in other expressions in types, such as the
417-
// arithmetic expression in the return type here.
418-
fn bad_function<const N: usize>() -> [u8; {N + 1}] {
419-
// Similarly not allowed for array repeat expressions.
420-
[1; {N + 1}]
421-
}
422-
```
414+
> [!EXAMPLE]
415+
> ```rust,compile_fail
416+
> // Examples where const parameters may not be used.
417+
>
418+
> // Not allowed to combine in other expressions in types, such as the
419+
> // arithmetic expression in the return type here.
420+
> fn bad_function<const N: usize>() -> [u8; {N + 1}] {
421+
> // Similarly not allowed for array repeat expressions.
422+
> [1; {N + 1}]
423+
> }
424+
> ```
423425
424426
r[generics.const.inferred]
425427
Where a const argument is expected, an `_` (optionally surrounded by any number of matching parentheses), called the *inferred const* ([generic argument rules][generics.arguments.complex-const-params], [array expression rules][expr.array.length-restriction]), can be used instead. This asks the compiler to infer the const argument if possible based on surrounding information.
@@ -453,33 +455,35 @@ fn f<const N: usize>(x: [u8; N]) -> [u8; _] { x }
453455
r[generics.const.variance]
454456
Unlike type and lifetime parameters, const parameters can be declared without being used inside of a parameterized item, with the exception of implementations as described in [generic implementations]:
455457

456-
```rust,compile_fail
457-
// ok
458-
struct Foo<const N: usize>;
459-
enum Bar<const M: usize> { A, B }
460-
461-
// ERROR: unused parameter
462-
struct Baz<T>;
463-
struct Biz<'a>;
464-
struct Unconstrained;
465-
impl<const N: usize> Unconstrained {}
466-
```
458+
> [!EXAMPLE]
459+
> ```rust,compile_fail
460+
> // ok
461+
> struct Foo<const N: usize>;
462+
> enum Bar<const M: usize> { A, B }
463+
>
464+
> // ERROR: unused parameter
465+
> struct Baz<T>;
466+
> struct Biz<'a>;
467+
> struct Unconstrained;
468+
> impl<const N: usize> Unconstrained {}
469+
> ```
467470
468471
r[generics.const.exhaustiveness]
469472
When resolving a trait bound obligation, the exhaustiveness of all implementations of const parameters is not considered when determining if the bound is satisfied. For example, in the following, even though all possible const values for the `bool` type are implemented, it is still an error that the trait bound is not satisfied:
470473
471-
```rust,compile_fail
472-
struct Foo<const B: bool>;
473-
trait Bar {}
474-
impl Bar for Foo<true> {}
475-
impl Bar for Foo<false> {}
476-
477-
fn needs_bar(_: impl Bar) {}
478-
fn generic<const B: bool>() {
479-
let v = Foo::<B>;
480-
needs_bar(v); // ERROR: trait bound `Foo<B>: Bar` is not satisfied
481-
}
482-
```
474+
> [!EXAMPLE]
475+
> ```rust,compile_fail
476+
> struct Foo<const B: bool>;
477+
> trait Bar {}
478+
> impl Bar for Foo<true> {}
479+
> impl Bar for Foo<false> {}
480+
>
481+
> fn needs_bar(_: impl Bar) {}
482+
> fn generic<const B: bool>() {
483+
> let v = Foo::<B>;
484+
> needs_bar(v); // ERROR: trait bound `Foo<B>: Bar` is not satisfied
485+
> }
486+
> ```
483487
484488
r[generics.const.arguments]
485489
### Const arguments
@@ -525,15 +529,16 @@ When there is ambiguity if a generic argument could be resolved as either a type
525529
526530
<!-- TODO: Rewrite the paragraph above to be in terms of namespaces, once namespaces are introduced, and it is clear which namespace each parameter lives in. -->
527531
528-
```rust,compile_fail
529-
type N = u32;
530-
struct Foo<const N: usize>;
531-
// The following is an error, because `N` is interpreted as the type alias `N`.
532-
fn foo<const N: usize>() -> Foo<N> { todo!() } // ERROR
533-
// Can be fixed by wrapping in braces to force it to be interpreted as the `N`
534-
// const parameter:
535-
fn bar<const N: usize>() -> Foo<{ N }> { todo!() } // ok
536-
```
532+
> [!EXAMPLE]
533+
> ```rust,compile_fail
534+
> type N = u32;
535+
> struct Foo<const N: usize>;
536+
> // The following is an error, because `N` is interpreted as the type alias `N`.
537+
> fn foo<const N: usize>() -> Foo<N> { todo!() } // ERROR
538+
> // Can be fixed by wrapping in braces to force it to be interpreted as the `N`
539+
> // const parameter:
540+
> fn bar<const N: usize>() -> Foo<{ N }> { todo!() } // ok
541+
> ```
537542
538543
r[generics.parameters.attributes]
539544
## Attributes
@@ -542,15 +547,16 @@ Generic parameters allow [attributes] on them. There are no built-in attributes
542547
543548
This example shows using a custom derive attribute to modify the meaning of a generic parameter.
544549
545-
<!-- ignore: requires proc macro derive -->
546-
```rust,ignore
547-
// Assume that the derive for MyFlexibleClone declared `my_flexible_clone` as
548-
// an attribute it understands.
549-
#[derive(MyFlexibleClone)]
550-
struct Foo<#[my_flexible_clone(unbounded)] H> {
551-
a: *const H
552-
}
553-
```
550+
> [!EXAMPLE]
551+
> <!-- ignore: requires proc macro derive -->
552+
> ```rust,ignore
553+
> // Assume that the derive for MyFlexibleClone declared `my_flexible_clone` as
554+
> // an attribute it understands.
555+
> #[derive(MyFlexibleClone)]
556+
> struct Foo<#[my_flexible_clone(unbounded)] H> {
557+
> a: *const H
558+
> }
559+
> ```
554560
555561
[array repeat expression]: expr.array
556562
[arrays]: type.array

0 commit comments

Comments
 (0)