rust-lang / rust-lang/rust

return_position_impl_trait_in_trait can not express static lifetime bound

Open
#117,210 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-impl-trait C-bug F-return_position_impl_trait_in_trait T-compiler T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code

I tried this code:

pub trait Test {
  fn log(&self);
}

struct A;
impl Test for A {
  fn log(&self) {
    todo!()
  }
}


pub trait MakeTest {
  fn make(&self) -> impl Test + 'static;
}

struct MakeTestA;

impl MakeTest for MakeTestA {
  fn make(&self) -> impl Test + 'static {
    A
  }
}

fn test(maker: impl MakeTest) -> impl Test + 'static {
  maker.make()
}

I expected to see this happen: compiled successfully

Instead, this happened: compiled with error

error[E0597]: `maker` does not live long enough
  --> src/lib.rs:26:3
   |
25 | fn test(maker: impl MakeTest) -> impl Test + 'static {
   |         ----- binding `maker` declared here
26 |   maker.make()
   |   ^^^^^-------
   |   |
   |   borrowed value does not live long enough
   |   argument requires that `maker` is borrowed for `'static`
27 | }
   | - `maker` dropped here while still borrowed

error[E0310]: the parameter type `impl MakeTest` may not live long enough
  --> src/lib.rs:26:3
   |
26 |   maker.make()
   |   ^^^^^^^^^^^^
   |   |
   |   the parameter type `impl MakeTest` must be valid for the static lifetime...
   |   ...so that the type `impl MakeTest` will meet its required lifetime bounds
   |
help: consider adding an explicit lifetime bound
   |
25 | fn test(maker: impl MakeTest + 'static) -> impl Test + 'static {
   |                              +++++++++

Some errors have detailed explanations: E0310, E0597.
For more information about an error, try `rustc --explain E0310`.
Version it worked on

It worked on nightly-2023-06-12 (at least, not the most recent one).

Version with regression

I'm testing in recent nightly 2023-10-21

Other info

I'm updating my project's nightly version and find it not work. I'm not sure if it's a real regression or if the return_position_impl_trait_in_trait's design has been changed.

Intuitively, I thought the above example should as the same as this one which works fine:

pub trait Test {
  fn log(&self);
}

struct A;
impl Test for A {
  fn log(&self) {
    todo!()
  }
}

pub trait MakeTest {
  type Test: Test + 'static;
  fn make(&self) -> Self::Test;
}

struct MakeTestA;

impl MakeTest for MakeTestA {
  type Test = A;

  fn make(&self) -> Self::Test {
    A
  }
}

fn test(maker: impl MakeTest) -> impl Test + 'static {
  maker.make()
}

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.

Research direction

Start by reproducing the provided example on nightly-2023-06-12 and recent nightly-2023-10-21, then compare the resulting diagnostics. Investigate whether the changed behavior is a regression or an intentional return-position impl Trait in trait design change; done means the expected behavior and resolution are documented and verified.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.