Skip to content
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

return_position_impl_trait_in_trait can not express static lifetime bound #117210

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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