rust-lang / rust-lang/rust

Confusing error around 2024 impl trait lifetime capture

Open
#128,113 2 comments 0 reactions 1 assignee View on GitHub

@compiler-errors is already working on this.

Since Jul 23, 2024.

A-diagnostics A-edition-2024 D-confusing F-lifetime_capture_rules_2024 I-edition-triaged T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I'm finding the error message for 2024 impl trait lifetime capture a little confusing. In the following example:

#![feature(lifetime_capture_rules_2024)]

trait Trait1 {
    type Item;
}
trait Trait2<'a> {}

struct Example;

impl Trait1 for Example {
    type Item = Element;
}

struct Element;
impl<'a> Trait2<'a> for Element {}

fn foo<'a>() -> impl for<'b> Trait1<Item = impl Trait2<'a>> {
    Example
}

Produces the following output:

error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
  --> src/lib.rs:19:44
   |
19 | fn foo<'a>() -> impl for<'b> Trait1<Item = impl Trait2<'a>> {
   |                                            ^^^^^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
   |
note: lifetime declared here
  --> src/lib.rs:19:26
   |
19 | fn foo<'a>() -> impl for<'b> Trait1<Item = impl Trait2<'a>> {
   |                          ^^

For more information about this error, try `rustc --explain E0657`.

For someone that is not familiar with how impl trait capturing works, it seems confusing to understand why the compiler thinks that impl Trait2 is trying to capture anything, since I'm not telling it to.

I'm not entirely certain what would help here, but here are some suggestions:

  • Indicate the exact lifetime (and exact impl trait) in the error message, instead of using generic statements like "all lifetimes". For example, it could say: impl Trait2 is capturing 'b. Be concrete and short about what is happening.
  • Show how to fix it (with + use<'a>). I assume this is blocked on precise_capturing, and I'm not sure if there are intentions to do that. It would be nice if that explanation also explained to the user why that works ("explicitly capturing 'a indicates that the impl Trait2 does not capture any other lifetimes").
  • Would also be nice if it also explained why this is an error. Perhaps give a small hint that "use<> is required to be explicit about which lifetimes are being captured" or whatever explanation makes sense.
  • Add a link to the edition-guide chapter that explains capture rules (@traviscross is currently working on these docs).
Version
rustc 1.82.0-nightly (92c6c0380 2024-07-21)
binary: rustc
commit-hash: 92c6c03805408a1a261b98013304e9bbf59ee428
commit-date: 2024-07-21
host: aarch64-apple-darwin
release: 1.82.0-nightly
LLVM version: 18.1.7

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.