Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Breakage caused by precise capturing (RFC 3617) #815

Open
4 tasks
obi1kenobi opened this issue Jul 13, 2024 · 2 comments
Open
4 tasks

Breakage caused by precise capturing (RFC 3617) #815

obi1kenobi opened this issue Jul 13, 2024 · 2 comments
Labels
A-lint Area: new or existing lint C-enhancement Category: raise the bar on expectations

Comments

@obi1kenobi
Copy link
Owner

obi1kenobi commented Jul 13, 2024


From the RFC:

In RFC 3498, we decided to capture all in-scope generic parameters in RPIT-like impl Trait opaque types, across all editions, for new features we were stabilizing such as return position impl Trait in Trait (RPITIT) and associated type position impl Trait (ATPIT), and to capture all in-scope generic parameters for RPIT on bare functions and on inherent functions and methods starting in the Rust 2024 edition. Doing this made the language more predictable and consistent, eliminated weird “tricks”, and, by solving key problems, allowed for the stabilization of RPITIT.

The new default behavior is "capture all generics that are in-scope." The use<...> clause below can be used to limit what gets captured.

Examples of the feature:

fn foo<'t, T, U>(_: &'t (), _: T, y: U) -> impl use<U> Sized { y }
//                                         ^^^^^^^^^^^^^^^^^
//                                         ^ Captures `U` only.
fn foo<'t, T>(_: &'t T) -> impl use<> Sized {}
//                         ^^^^^^^^^^^^^^^^
//                         ^ Captures nothing.

trait Trait<'a, 'b> {
    fn foo(_: &'a (), _: &'b ()) -> impl use<'a, Self> Sized;
    //                              ^^^^^^^^^^^^^^^^^^^^^^^^
    //                              ^ Captures `'a` and `Self` only.
}

Breaking changes

Capturing an additional type parameter in function/method

  • implemented?

Witness:

// The old `foo` implementation
fn foo_old<T>(_: T) -> impl use<> Sized {}

fn foo<T>(_: T) -> impl Sized {}
//                 ^^^^^^^^^^
//                 ^ The returned opaque type captures `T`
//                   but the hidden type does not.

fn bar(x: ()) -> impl Sized + 'static {
    foo(&x)
//~^ ERROR returns a value referencing data owned by the
//~|       current function
}

Capturing an additional lifetime/type/const parameter in non-sealed trait function

  • implemented?

Witness: trait implementations must update their capture definition to match

Capturing an additional type parameter in externally-callable trait function, regardless of whether the trait is sealed

  • implemented?

Note: will need to be implemented only over sealed traits, to avoid conflicting with the "any parameter in unsealed trait" rule immediately above.

Witness: Same as "additional type in function/method."

Removing the capture of a lifetime/type/const parameter in non-sealed trait function

  • implemented?

Witness: trait implementations must update their capture definition to match

@obi1kenobi
Copy link
Owner Author

obi1kenobi commented Jul 13, 2024

Open questions:

  • Is capturing an additional lifetime or const on functions breaking?
  • Is removing the capture of a lifetime/type/const generic parameter on functions breaking?

We need a witness (example of breakage) case for each, to help us craft good diagnostic messages.

@obi1kenobi obi1kenobi added A-lint Area: new or existing lint C-enhancement Category: raise the bar on expectations labels Jul 13, 2024
@obi1kenobi
Copy link
Owner Author

This feature was stabilized in Rust 1.82, and the release blog post has more information on how it works: https://blog.rust-lang.org/2024/10/17/Rust-1.82.0.html

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-lint Area: new or existing lint C-enhancement Category: raise the bar on expectations
Projects
None yet
Development

No branches or pull requests

1 participant