Skip to content

Unclear compiler error when impl Trait return value captures non-'static argument #82171

Open
@ramosbugs

Description

@ramosbugs

(cc @estebank)

I tried this code (the explicit 'static lifetime is unnecessary but emphasizes the implicit 'static requirement of impl Trait):

fn foo<T>(a: T) -> impl Iterator<Item = String> + 'static
where
    T: std::fmt::Display
{
    std::iter::once(a.to_string())
}

fn bar(a: &str) -> impl Iterator<Item = String> + 'static {
    foo(a)
}

See playground.

I expected to see this happen:

Successful compilation or a clear error message suggesting that impl Trait can't be used in this way due to the non-'static lifetime of foo's argument a.

Instead, this happened:

error[E0759]: `a` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
 --> src/lib.rs:9:9
  |
8 | fn bar(a: &str) -> impl Iterator<Item = String> + 'static {
  |           ---- this data with an anonymous lifetime `'_`...
9 |     foo(a)
  |         ^ ...is captured here...
  |
note: ...and is required to live as long as `'static` here
 --> src/lib.rs:8:20
  |
8 | fn bar(a: &str) -> impl Iterator<Item = String> + 'static {
  |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `a`
  |
8 | fn bar(a: &str) -> impl Iterator<Item = String> + '_ {
  |                                                   ^^
help: alternatively, add an explicit `'static` bound to this reference
  |
8 | fn bar(a: &'static str) -> impl Iterator<Item = String> + 'static {
  |           ^^^^^^^^^^^^

foo's return value isn't dependent on a's lifetime since to_string converts it to an owned String. Returning Box<dyn Iterator<Item = String>> instead of using impl Trait fixes the error.

Neither of the compiler's suggestions are the "right" fix here, since I'd like the return value to have a 'static lifetime but don't want to require a to have one.

I think the ideal fix (to the error message) would be something along the lines of:

  • a short explanation of why impl Trait doesn't allow the return value not to depend on the lifetime of a (maybe with a tracking issue if this limitation is being addressed)
  • an additional suggestion to use Box<dyn Trait> and/or a concrete type

Meta

rustc --version --verbose:

rustc 1.50.0 (cb75ad5db 2021-02-10)
binary: rustc
commit-hash: cb75ad5db02783e8b0222fee363c5f63f7e2cf5b
commit-date: 2021-02-10
host: x86_64-apple-darwin
release: 1.50.0

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-lifetimesArea: Lifetimes / regionsC-bugCategory: This is a bug.D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.D-papercutDiagnostics: An error or lint that needs small tweaks.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.fixed-by-TAITFixed by the feature `type_alias_impl_trait`.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions