-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Closed
Copy link
Labels
C-bugCategory: This is a bug.Category: This is a bug.
Description
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
// }
}
}
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
Metadata
Metadata
Assignees
Labels
C-bugCategory: This is a bug.Category: This is a bug.
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
[-]Lifetime inference fails with returning an instance of a GAT[/-][+]Lifetime inference fails when construct then returning an instance of a GAT[/+]compiler-errors commentedon Jan 13, 2022
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 parsingPath<'lifetime>
since that's also what's wrong with the second solution.@rustbot claim
hlb8122 commentedon 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 astruct
, 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 commentedon Jan 13, 2022
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 commentedon Jan 13, 2022
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.
Rollup merge of rust-lang#92918 - compiler-errors:gat-expr-lifetime-e…
Rollup merge of rust-lang#92918 - compiler-errors:gat-expr-lifetime-e…