Skip to content

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

Open
@RustyYato

Description

@RustyYato
Contributor

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 { ... }

Activity

RustyYato

RustyYato commented on Jan 13, 2021

@RustyYato
ContributorAuthor

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

ocstl

ocstl commented on Dec 14, 2021

@ocstl

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)A-lifetimesArea: Lifetimes / regionsC-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @mbrubeck@ocstl@RustyYato

        Issue actions

          "Associated type doesn't live long enough", even though it does · Issue #80986 · rust-lang/rust