Improve example on avoiding HR lifetime capture

We have an example showing how to avoid capturing a higher ranked
lifetime in a nested opaque type so that the code can be migrated to
Rust 2024.  However, because we didn't parameterize the trait in the
example with a lifetime, the code could be migrated by just removing
the `for<..>` binder.  This makes the example weaker than it could be,
so let's strengthen it by parameterizing the trait.

(Thanks to aliemjay for raising this point.)
This commit is contained in:
Travis Cross 2024-04-28 03:47:30 +00:00
parent f01222877d
commit b02f1aabcc
1 changed files with 8 additions and 7 deletions

View File

@ -257,13 +257,14 @@ mod _0 {
## Avoiding capture of higher ranked lifetimes in nested opaques
For implementation reasons, Rust does not yet support higher ranked lifetime bounds on nested opaque types (see [#104288][]). However, according to the Lifetime Capture Rules 2024, a nested `impl Trait` opaque type *must* capture all generic parameters in scope, including higher ranked ones. Therefore, in Rust 2024, this code fails to compile:
According to the Lifetime Capture Rules 2024, a nested `impl Trait` opaque type *must* capture all generic parameters in scope, including higher ranked ones. However, for implementation reasons, Rust does not yet support higher ranked lifetime bounds on nested opaque types (see [#104288][]). Therefore, in Rust 2024, this code, which is valid in Rust 2021, fails to compile:
```rust
trait Trait { type Ty; }
impl<F> Trait for F { type Ty = (); }
//@ edition: 2024
trait Trait<'a> { type Ty; }
impl<F> Trait<'_> for F { type Ty = (); }
fn foo() -> impl for<'a> Trait<Ty = impl Sized> {
fn foo() -> impl for<'a> Trait<'a, Ty = impl Sized> {
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime
//~| from outer `impl Trait`
fn f(_: &()) -> &'static () { &() }
@ -274,9 +275,9 @@ fn foo() -> impl for<'a> Trait<Ty = impl Sized> {
With `use<..>`, we can avoid capturing this higher ranked lifetime, allowing compilation:
```rust
fn foo() -> impl for<'a> Trait<Ty = impl use<> Sized> {
// ^^^^^^^^^^^^^^^^
// ^ Captures nothing.
fn foo() -> impl for<'a> Trait<'a, Ty = impl use<> Sized> {
// ^^^^^^^^^^^^^^^^
// ^ Captures nothing.
fn f(_: &()) -> &'static () { &() }
f
}