From c0f756e054019646513e9b20f6d4f8193cc0c5b2 Mon Sep 17 00:00:00 2001 From: Taylor Yu Date: Tue, 6 Jul 2021 19:13:37 -0500 Subject: [PATCH 1/4] move text about checking of bounds on generics Move text about the timing of checking of bounds on generics from the "Where clauses" subsection to "Trait and lifetime bounds", where it makes more sense. Split parts of the example accordingly. Correct an error about when `Clone`, `Copy`, and `Sized` trait bounds are checked. --- src/items/generics.md | 19 +++---------------- src/trait-bounds.md | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 16 deletions(-) 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..536b8c66b 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][arrays]. +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` @@ -142,11 +162,16 @@ 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 [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 From 50c855b244677026076aa666cfd6b2e05be8be8c Mon Sep 17 00:00:00 2001 From: Taylor Yu Date: Tue, 13 Jul 2021 19:42:18 -0500 Subject: [PATCH 2/4] update moved text to one line per sentence --- src/trait-bounds.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trait-bounds.md b/src/trait-bounds.md index 536b8c66b..ab998ab56 100644 --- a/src/trait-bounds.md +++ b/src/trait-bounds.md @@ -73,8 +73,8 @@ 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. +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][arrays]. From a1625965afe5fbec615a6d458a6b9ee0f24bd448 Mon Sep 17 00:00:00 2001 From: Taylor Yu Date: Wed, 14 Jul 2021 19:07:04 -0500 Subject: [PATCH 3/4] update cross-reference to slice --- src/trait-bounds.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/trait-bounds.md b/src/trait-bounds.md index ab998ab56..64693c52f 100644 --- a/src/trait-bounds.md +++ b/src/trait-bounds.md @@ -77,7 +77,7 @@ Bounds that don't use the item's parameters or [higher-ranked lifetimes] are che 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][arrays]. +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 @@ -171,6 +171,7 @@ fn call_on_ref_zero(f: F) where F: for<'a> Fn(&'a i32) { [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 From f5088eaa70292be9300162da47b34600a5890aa6 Mon Sep 17 00:00:00 2001 From: Taylor Yu Date: Wed, 7 Jul 2021 23:20:53 -0500 Subject: [PATCH 4/4] fix wording/punctuation in "Lifetime bounds" Clarify that "outlives" really means "lives at least as long as". Also fix some more minor punctuation and wording issues. --- src/trait-bounds.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/trait-bounds.md b/src/trait-bounds.md index 64693c52f..4dda1d20f 100644 --- a/src/trait-bounds.md +++ b/src/trait-bounds.md @@ -103,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 { @@ -114,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 @@ -137,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) { @@ -147,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.