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

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

Closed
hlb8122 opened this issue Jan 13, 2022 · 4 comments · Fixed by #92918
Closed

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

hlb8122 opened this issue Jan 13, 2022 · 4 comments · Fixed by #92918
Assignees
Labels
C-bug Category: This is a bug.

Comments

@hlb8122
Copy link

hlb8122 commented Jan 13, 2022

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
@hlb8122 hlb8122 added the C-bug Category: This is a bug. label Jan 13, 2022
@hlb8122 hlb8122 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 Jan 13, 2022
@compiler-errors
Copy link
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
Copy link
Author

hlb8122 commented Jan 13, 2022

@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
Copy link
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
Copy link
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.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 30, 2022
…lision, r=jackh726

Allow eliding GATs in expression position

Thoughts on whether this is worthwhile?

Fixes rust-lang#92836

r? `@jackh726`
@bors bors closed this as completed in 55d5513 Jan 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants