Skip to content

Precice capturing does not normalize aliases/projections (e.g. Self::Assoc) #140274

New issue

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

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

Already on GitHub? Sign in to your account

Open
QuineDot opened this issue Apr 24, 2025 · 1 comment
Open
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@QuineDot
Copy link

I tried this code:

pub trait Trait<'a, T> {
    type Item;
    fn method(&self) -> Option<impl Iterator<Item = Self::Item>>;
}

impl<'a, 's, T, U> Trait<'a, T> for &'s U
where
    U: std::ops::Deref<Target: Sized>,
{
    type Item = U::Target;
    #[allow(refining_impl_trait)]
    fn method(&self) -> Option<impl Iterator<Item = Self::Item> + use<T, U>> {
        None::<std::vec::IntoIter<U::Target>>
    }
}

I expected to see this happen (in increasing order of preference):

  • Underline Self specifically as the origin of lifetime capturing (not the entire opaque)
  • Suggest the following fix
    -    fn method(&self) -> Option<impl Iterator<Item = Self::Item> + use<T, U>> {
    +    fn method(&self) -> Option<impl Iterator<Item = U::Target> + use<T, U>> {
  • Compile successfully

Further explanation: It's natural to copy the bounds from the trait definition. Moreover one may, say, add precise captures during the course of development by editing an opaque that is already present (which may use aliases such as Self). It's easy to miss that any use of Self can pull in other parameters. In the example it pulls in not only the lifetime in the implementing type, but also the one in the trait:

impl Iterator<Item = <&'s U as Trait<'a, T>>::Item>

It would be a breaking change to make Self::Item capture the lifetimes, so normalizing shouldn't be a future compatibility concern for the example at least.

If normalization/successful compilation isn't possible for whatever reason, this can be considered purely a diagnostic issue.


Instead, this happened:

error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
  --> src/lib.rs:13:32
   |
6  | impl<'a, 's, T, U> Trait<'a, T> for &'s U
   |      -- this lifetime parameter is captured
...
13 |     fn method(&self) -> Option<impl Iterator<Item = Self::Item> + use<T, U>> {
   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime captured due to being mentioned in the bounds of the `impl Trait`

error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
  --> src/lib.rs:13:32
   |
6  | impl<'a, 's, T, U> Trait<'a, T> for &'s U
   |          -- this lifetime parameter is captured
...
13 |     fn method(&self) -> Option<impl Iterator<Item = Self::Item> + use<T, U>> {
   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime captured due to being mentioned in the bounds of the `impl Trait`

Meta

Playground beta and nightly

  • Build using the Beta version: 1.87.0-beta.3 (2025-04-07 a22ecb5)
  • Build using the Nightly version: 1.88.0-nightly (2025-04-07 e643f59)
  • Playground link
@QuineDot QuineDot added the C-bug Category: This is a bug. label Apr 24, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 24, 2025
@compiler-errors
Copy link
Member

Yeah this is purely a diagnostics issue. It's not possible to eagerly normalize in bound computation.

@lolbinarycat lolbinarycat added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Apr 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants