Skip to content

Lifetime inference fails when construct then returning an instance of a GAT #92836

@hlb8122

Description

@hlb8122

I tried this code:

#![feature(generic_associated_types)]

pub trait Trait  {
    type Assoc<'a> where Self: 'a;

    fn f(&self) -> Self::Assoc<'_>;
}

pub struct Struct {
    item: f32
}

pub struct GenericStruct<'a> {
    ref_item: &'a f32
}

impl Trait for Struct {
    type Assoc<'a> = GenericStruct<'a>;

    fn f(&self) -> Self::Assoc<'_> {
        // This doesn't work
        Self::Assoc {
            ref_item: &self.item
        }
        
        // This doesn't work
        // Self::Assoc<'_> {
        //     ref_item: &self.item
        // }
        
        // This works, but concrete name is not always readily available
        // GenericStruct {
        //     ref_item: &self.item
        // }
        
        // This works
        // type Fix<'a> = <Struct as Trait>::Assoc<'a>;
        // Fix {
        //     ref_item: &self.item
        // }
    }
}

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=ad49e24a0e96620b942d3abd23d49549

I expected to see this happen: the lifetime is correctly inferred when using

Self::Assoc {
    ref_item: &self.item
}

Instead, this happened: I have to use one of the work arounds described in the linked code.

Swap from GAT lifetime to the trait parameterized by a lifetime it works:
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=551e676af610e612a7627661d6c5ca05

Meta

rustc --version --verbose:

rustc 1.60.0-nightly (1409c015b 2022-01-11)
binary: rustc
commit-hash: 1409c015b44a4d4d38bef2250b2a37c17b8b7463
commit-date: 2022-01-11
host: x86_64-unknown-linux-gnu
release: 1.60.0-nightly
LLVM version: 13.0.0

Activity

changed the title [-]Lifetime inference fails with returning an instance of a GAT[/-] [+]Lifetime inference fails when construct then returning an instance of a GAT[/+] on Jan 13, 2022
compiler-errors

compiler-errors commented on Jan 13, 2022

@compiler-errors
Member

Interested in fixing this.

I think all we need to do is treat Self::Assoc like other paths with elided lifetimes (e.g. GenericStruct { .. }). @jackh726, you're the go-to person for GATs, right? If so, does that sound correct?

Secondly I might also put up a PR that suggests adding :: when parsing Path<'lifetime> since that's also what's wrong with the second solution.

@rustbot claim

hlb8122

hlb8122 commented on Jan 13, 2022

@hlb8122
Author

@compiler-errors ah yes, good catch, the second solution does work with ::.

In the way I had originally encountered this it didn't work without more nightly features (more_qualified_paths) - a GAT, on a trait, on a struct, which parametrized a trait. Which left the type alias way the only way around.

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=e3fb9ce0ad4570ff66651eb937f7a0f7

jackh726

jackh726 commented on Jan 13, 2022

@jackh726
Member

I think all we need to do is treat Self::Assoc like other paths with elided lifetimes (e.g. GenericStruct { .. }). @jackh726, you're the go-to person for GATs, right? If so, does that sound correct?

I don't know if I've looked at this code before. But seems about right. I'm wondering if something like <Self as Trait<'_>>::Assoc works and there's just code somewhere that doesn't take into account that the associated type itself can have substs.

jackh726

jackh726 commented on Jan 13, 2022

@jackh726
Member

This might be a little bit difficult though. When using a concrete struck like GenericStruct<'_>, we can infer that lifetime because we know how it's used in the struct itself. With associated types, we don't know, necessarily. In a way, I would expect that to be somewhat opaque, tbh.

I'm not sure how I feel about this tbh. If you can fix it, I'd probably want to get some second thoughts before merging.

added 2 commits that reference this issue on Jan 30, 2022
ef64c52
55d5513
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

C-bugCategory: This is a bug.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @compiler-errors@hlb8122@jackh726

    Issue actions

      Lifetime inference fails when construct then returning an instance of a GAT · Issue #92836 · rust-lang/rust