Skip to content

return_position_impl_trait_in_trait can not express static lifetime bound #117210

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

Open
mikialex opened this issue Oct 26, 2023 · 6 comments
Open
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. F-return_position_impl_trait_in_trait `#![feature(return_position_impl_trait_in_trait)]` T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@mikialex
Copy link

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()
}
@mikialex mikialex added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Oct 26, 2023
@rustbot rustbot added I-prioritize Issue: Indicates that prioritization has been requested for this issue. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Oct 26, 2023
@apiraino
Copy link
Contributor

Might be a duplicate of #117055 (in case feel free to close in favour of that issue)

@rustbot label -I-prioritize +T-compiler

@rustbot rustbot added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Oct 26, 2023
@lcnr
Copy link
Contributor

lcnr commented Oct 26, 2023

cc @compiler-errors

@compiler-errors
Copy link
Member

This is a manifestation of #42940, which I attempted to fix in #116040, but which needs much more involved changes to fix.

@compiler-errors compiler-errors added A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. T-types Relevant to the types team, which will review and decide on the PR/issue. F-return_position_impl_trait_in_trait `#![feature(return_position_impl_trait_in_trait)]` and removed regression-untriaged Untriaged performance or correctness regression. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Oct 27, 2023
@BlackStone1123
Copy link

Any progress with this issue? The return position impl trait has been unreasonable bounded with arguments lifetime ,and I cannot even bypass this issue with unsafe, looking forward for solution.

@lcnr
Copy link
Contributor

lcnr commented Feb 19, 2024

you will be able to work around this once type_alias_impl_trait, or associated_type_position_impl_trait is stable by using a separate type alias instead

@EqualMa
Copy link
Contributor

EqualMa commented Jun 20, 2024

I run into this issue with code like the following:

trait Trait {}

trait TraitReturningImplTrait {
    fn method(&self) -> impl 'static + Trait;
}

fn test(v: impl TraitReturningImplTrait) -> impl 'static + Trait {
    v.method()
}

Here is the playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=32a26fc26cf8528c1a0a1d195daac25d

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. F-return_position_impl_trait_in_trait `#![feature(return_position_impl_trait_in_trait)]` T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants