Skip to content

Commit

Permalink
Remove discussion of automatically inserting use<..>
Browse files Browse the repository at this point in the history
Rather than framing this as that the compiler automatically inserts
`use<..>` bounds, let's just describe the implicit captures behavior
directly.
  • Loading branch information
traviscross committed Aug 5, 2024
1 parent d7f8c13 commit 28a2fd5
Showing 1 changed file with 8 additions and 8 deletions.
16 changes: 8 additions & 8 deletions src/rust-2024/rpit-lifetime-capture.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 10,8 @@ This chapter describes changes related to the **Lifetime Capture Rules 2024** in
## Summary

- In all editions, `use<..>` bounds allow for capturing only the lifetime parameters needed in RPIT opaque types.
- If a `use<..>` bound is elided (i.e. not present) then the compiler automatically inserts one according to edition-specific rules.
- In Rust 2024, *all* in-scope generic parameters, including lifetime parameters, are included in these automatically inserted `use<..>` bounds.
- If a `use<..>` bound is elided (i.e. not present) then the compiler uses edition-specific rules to decide which in-scope generic parameters to capture implicitly.
- In Rust 2024, *all* in-scope generic parameters, including lifetime parameters, are implicitly captured when the `use<..>` bound is elided.
- Uses of the `Captures` trick (`Captures<..>` bounds) and of the outlives trick (e.g. `'_` bounds) can be replaced by `use<..>` bounds (in all editions) or removed entirely (in Rust 2024).

## Details
Expand Down Expand Up @@ -73,9 73,9 @@ The bounds list of an RPIT opaque type may contain at most one `use<..>` bound.

### Edition-specific rules for elided `use<..>` bounds

If the `use<..>` bound is *elided* (i.e., not present), then the compiler automatically inserts one according to edition-specific rules.
If the `use<..>` bound is *elided* (i.e., not present), then the compiler uses edition-specific rules to decide which in-scope generic parameters to capture implicitly.

In all editions, all in-scope type and const generic parameters are added to this automatically-inserted `use<..>` bound. E.g.:
In all editions, all in-scope type and const generic parameters are captured implicitly when the `use<..>` bound is elided. E.g.:

```rust
# #![feature(precise_capturing)]
Expand All @@ -87,7 87,7 @@ fn f_elided<T, const C: usize>() -> impl Sized {}
fn f_explicit<T, const C: usize>() -> impl Sized use<T, C> {}
```

In Rust 2021 and earlier editions, generic lifetime parameters are *not* included in this automatically-inserted `use<..>` bound for RPIT opaque types in the signature of bare functions and associated functions and methods within inherent impls. However, starting in Rust 2024, these in-scope generic lifetime parameters *are* included. E.g.:
In Rust 2021 and earlier editions, when the `use<..>` bound is elided, generic lifetime parameters are *not* implicitly captured in RPIT opaque types in the signature of bare functions and associated functions and methods within inherent impls. However, starting in Rust 2024, these in-scope generic lifetime parameters *are* implicitly captured. E.g.:

```rust
# #![feature(precise_capturing)]
Expand All @@ -98,11 98,11 @@ fn f_2021(_: &()) -> impl Sized use<> {}
fn f_2024(_: &()) -> impl Sized use<'_> {}
```

This makes the behavior consistent with RPIT opaque types in the signature of associated functions and methods within trait impls, uses of RPIT within trait definitions (RPITIT), and opaque `Future` types created by `async fn`, all of which capture all in-scope generic lifetime parameters by default in all editions.
This makes the behavior consistent with RPIT opaque types in the signature of associated functions and methods within trait impls, uses of RPIT within trait definitions (RPITIT), and opaque `Future` types created by `async fn`, all of which implicitly capture all in-scope generic lifetime parameters in all editions when the `use<..>` bound is elided.

### Outer generic parameters

When we say that an RPIT opaque type captures all in-scope generic parameters, note that this includes generic parameters from an outer impl. E.g.:
Generic parameters from an outer impl are considered to be in scope when deciding what is implicitly captured. E.g.:

```rust
# #![feature(precise_capturing)]
Expand Down Expand Up @@ -143,7 143,7 @@ fn f_2021() -> impl for<'a> Tr<'a, Ty = impl Copy use<>> {}

### Argument position impl Trait (APIT)

Anonymous (i.e. unnamed) generic parameters created by the use of APIT (argument position impl Trait) are considered to be in scope when inserting an explicit `use<..>` bound for an elided one. E.g.:
Anonymous (i.e. unnamed) generic parameters created by the use of APIT (argument position impl Trait) are considered to be in scope. E.g.:

```rust
# #![feature(precise_capturing)]
Expand Down

0 comments on commit 28a2fd5

Please sign in to comment.