Skip to content

"Associated type doesn't live long enough", even though it does #80986

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

Open
RustyYato opened this issue Jan 13, 2021 · 2 comments
Open

"Associated type doesn't live long enough", even though it does #80986

RustyYato opened this issue Jan 13, 2021 · 2 comments
Labels
A-associated-items Area: Associated items (types, constants & functions) A-lifetimes Area: Lifetimes / regions C-bug Category: This is a bug.

Comments

@RustyYato
Copy link
Contributor

RustyYato commented Jan 13, 2021

I tried this code:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0474ce6d89ae44d17d9ef2df99c0883f

struct Foo<T>([T]);

impl<I: core::slice::SliceIndex<[T]>, T> core::ops::Index<I> for Foo<T>
where
    I::Output: AsRef<[u8]>,
{
    type Output = [u8];

    fn index(&self, index: I) -> &Self::Output {
        self.0[index].as_ref()
    }
}

I expected this to compile, because lifetime elision enforces that I::Output will live as long as self, and that SomethingElse will live as long as I::Output, and by transitivity SomethingElse will live as long as self.

However, I got to following

error message
error[E0311]: the associated type `<I as SliceIndex<[T]>>::Output` may not live long enough
  --> src/lib.rs:11:9
   |
11 |         self.0[index].as_ref()
   |         ^^^^^^^^^^^^^
   |
note: the associated type `<I as SliceIndex<[T]>>::Output` must be valid for the anonymous lifetime #1 defined on the method body at 10:5...
  --> src/lib.rs:10:5
   |
10 |     fn index(&self, index: I) -> &Self::Output {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that the reference type `&<I as SliceIndex<[T]>>::Output` does not outlive the data it points at
  --> src/lib.rs:11:9
   |
11 |         self.0[index].as_ref()
   |         ^^^^^^^^^^^^^

error[E0311]: the associated type `<I as SliceIndex<[T]>>::Output` may not live long enough
  --> src/lib.rs:11:9
   |
11 |         self.0[index].as_ref()
   |         ^^^^^^^^^^^^^
   |
note: the associated type `<I as SliceIndex<[T]>>::Output` must be valid for the anonymous lifetime #1 defined on the method body at 10:5...
  --> src/lib.rs:10:5
   |
10 |     fn index(&self, index: I) -> &Self::Output {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that the type `<I as SliceIndex<[T]>>::Output` is not borrowed for too long
  --> src/lib.rs:11:9
   |
11 |         self.0[index].as_ref()
   |         ^^^^^^^^^^^^^

error[E0311]: the associated type `<I as SliceIndex<[T]>>::Output` may not live long enough
  --> src/lib.rs:11:23
   |
11 |         self.0[index].as_ref()
   |                       ^^^^^^
   |
note: the associated type `<I as SliceIndex<[T]>>::Output` must be valid for the anonymous lifetime #1 defined on the method body at 10:5...
  --> src/lib.rs:10:5
   |
10 |     fn index(&self, index: I) -> &Self::Output {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that the reference type `&<I as SliceIndex<[T]>>::Output` does not outlive the data it points at
  --> src/lib.rs:11:23
   |
11 |         self.0[index].as_ref()
   |                       ^^^^^^

error: aborting due to 3 previous errors

error: could not compile `playground`

To learn more, run the command again with --verbose.

This is not specific to AsRef, any function that has the following signature will fail to compile

fn method(output: &I::Output) -> &SomethingElse { ... }
@RustyYato RustyYato added the C-bug Category: This is a bug. label Jan 13, 2021
@RustyYato
Copy link
Contributor Author

This might be related to #77654 or #63253, based on a brief look at those two issues

@mbrubeck mbrubeck added A-associated-items Area: Associated items (types, constants & functions) A-lifetimes Area: Lifetimes / regions labels Jan 25, 2021
@ocstl
Copy link

ocstl commented Dec 14, 2021

This seems to be a different issue, since both of those issues no longer fail to compile.

I may be missing something (and I am not an expert), but there doesn't seem to be any link between I::Output and Index::Output, hence no link between the lifetimes.

Rewriting it this way seems to correct the issue (playground link):

struct Foo<T>([T]);

impl<I: core::slice::SliceIndex<[T]>, T> core::ops::Index<I> for Foo<T>
where
    I::Output: AsRef<[u8]>,
{
    type Output = I::Output;

    fn index(&self, index: I) -> &Self::Output {
        &self.0[index]
    }
}

Again, I may be missing something, so feel free to correct me if I misunderstand the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) A-lifetimes Area: Lifetimes / regions C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants