diff --git a/src/items/generics.md b/src/items/generics.md index 686b6661d..e9c11ffcf 100644 --- a/src/items/generics.md +++ b/src/items/generics.md @@ -230,23 +230,13 @@ parameters. The `for` keyword can be used to introduce [higher-ranked lifetimes]. It only allows [_LifetimeParam_] parameters. -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 -bound on a mutable reference, [trait object] or [slice][arrays] or `Sized` as a -bound on a trait object or slice. - -```rust,compile_fail +```rust struct A where T: Iterator, // Could use A instead - T::Item: Copy, - String: PartialEq, + T::Item: Copy, // Bound on an associated type + String: PartialEq, // Bound on `String`, using the type parameter i32: Default, // Allowed, but not useful - i32: Iterator, // Error: the trait bound is not satisfied - [T]: Copy, // Error: the trait bound is not satisfied { f: T, } @@ -303,9 +293,6 @@ struct Foo<#[my_flexible_clone(unbounded)] H> { [path expression]: ../expressions/path-expr.md [raw pointers]: ../types/pointer.md#raw-pointers-const-and-mut [references]: ../types/pointer.md#shared-references- -[`Clone`]: ../special-types-and-traits.md#clone -[`Copy`]: ../special-types-and-traits.md#copy -[`Sized`]: ../special-types-and-traits.md#sized [structs]: structs.md [tuples]: ../types/tuple.md [trait object]: ../types/trait-object.md diff --git a/src/trait-bounds.md b/src/trait-bounds.md index 0bd6e9b1d..4dda1d20f 100644 --- a/src/trait-bounds.md +++ b/src/trait-bounds.md @@ -73,6 +73,26 @@ fn name_figure( } ``` +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 using the item, even if the use does not provide a concrete type. +It is an error to have `Copy` or `Clone` as a bound on a mutable reference, [trait object], or [slice]. +It is an error to have `Sized` as a bound on a trait object or slice. + +```rust,compile_fail +struct A<'a, T> +where + i32: Default, // Allowed, but not useful + i32: Iterator, // Error: `i32` is not an iterator + &'a mut T: Copy, // (at use) Error: the trait bound is not satisfied + [T]: Sized, // (at use) Error: size cannot be known at compilation +{ + f: &'a T, +} +struct UsesA<'a, T>(A<'a, T>); +``` + Trait and lifetime bounds are also used to name [trait objects]. ## `?Sized` @@ -83,9 +103,9 @@ not be used as a bound for other types. ## Lifetime bounds -Lifetime bounds can be applied to types or other lifetimes. The bound `'a: 'b` -is usually read as `'a` *outlives* `'b`. `'a: 'b` means that `'a` lasts longer -than `'b`, so a reference `&'a ()` is valid whenever `&'b ()` is valid. +Lifetime bounds can be applied to types or to other lifetimes. +The bound `'a: 'b` is usually read as `'a` *outlives* `'b`. +`'a: 'b` means that `'a` lasts at least as long as `'b`, so a reference `&'a ()` is valid whenever `&'b ()` is valid. ```rust fn f<'a, 'b>(x: &'a i32, mut y: &'b i32) where 'a: 'b { @@ -94,9 +114,8 @@ fn f<'a, 'b>(x: &'a i32, mut y: &'b i32) where 'a: 'b { } ``` -`T: 'a` means that all lifetime parameters of `T` outlive `'a`. For example if -`'a` is an unconstrained lifetime parameter then `i32: 'static` and -`&'static str: 'a` are satisfied but `Vec<&'a ()>: 'static` is not. +`T: 'a` means that all lifetime parameters of `T` outlive `'a`. +For example, if `'a` is an unconstrained lifetime parameter, then `i32: 'static` and `&'static str: 'a` are satisfied, but `Vec<&'a ()>: 'static` is not. ## Higher-ranked trait bounds @@ -117,8 +136,7 @@ impl<'a> PartialEq for &'a T { and could then be used to compare a `&'a T` with any lifetime to an `i32`. -Only a higher-ranked bound can be used here as the lifetime of the reference is -shorter than a lifetime parameter on the function: +Only a higher-ranked bound can be used here, because the lifetime of the reference is shorter than any possible lifetime parameter on the function: ```rust fn call_on_ref_zero(f: F) where for<'a> F: Fn(&'a i32) { @@ -127,7 +145,7 @@ fn call_on_ref_zero(f: F) where for<'a> F: Fn(&'a i32) { } ``` -Higher-ranked lifetimes may also be specified just before the trait, the only +Higher-ranked lifetimes may also be specified just before the trait: the only difference is the scope of the lifetime parameter, which extends only to the end of the following trait instead of the whole bound. This function is equivalent to the last one. @@ -142,11 +160,17 @@ fn call_on_ref_zero(f: F) where F: for<'a> Fn(&'a i32) { [LIFETIME_OR_LABEL]: tokens.md#lifetimes-and-loop-labels [_GenericParams_]: items/generics.md [_TypePath_]: paths.md#paths-in-types +[`Clone`]: special-types-and-traits.md#clone +[`Copy`]: special-types-and-traits.md#copy [`Sized`]: special-types-and-traits.md#sized +[arrays]: types/array.md [associated types]: items/associated-items.md#associated-types [supertraits]: items/traits.md#supertraits [generic]: items/generics.md +[higher-ranked lifetimes]: #higher-ranked-trait-bounds +[slice]: types/slice.md [Trait]: items/traits.md#trait-bounds +[trait object]: types/trait-object.md [trait objects]: types/trait-object.md [where clause]: items/generics.md#where-clauses