-
Notifications
You must be signed in to change notification settings - Fork 6
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
GATs can not refer to other GATs in trait requirement's associated types #11
Comments
Thanks for reporting this, I was indeed unaware of this issue. A minimal reproduction of the problematic code emitted by nougat is, I believe: macro_rules! Where {(
$T:ty : $lt:lifetime $(,)?
) => (
[&$lt $T; 0]
)}
trait Trait
:
for<'any> TraitItem<'any> +
for<'any> TraitIterator<'any> +
{}
trait TraitItem<'a, Bound = Where!(Self : 'a)> {
type T;
}
trait TraitIterator<'b, Bound = Where!(Self : 'b)> {
type T : Iterator<Item = <Self as TraitItem<'b>>::T>;
} |
Now, generating something like: trait Trait
:
for<'any> TraitItem<'any> +
for<'any> TraitIterator<'any> +
{}
trait TraitItem<'a, Bound = Where!(Self : 'a)>
:
- 'a + for<'any> TraitIterator<'any> +
+ // if it were added, we'd have a "cyclic requirements" error
{
type T;
}
trait TraitIterator<'b, Bound = Where!(Self : 'b)>
:
+ 'b + for<'any> TraitItem<'any>
{
type T : Iterator<Item = <Self as TraitItem<'b>>::T>;
} seems to fix the issue, but now we have another problem: the macro cannot really distinguish between the nature of the So in order to support this, we'd need some kind of annotation on the original trait definition to nudge #[gat]
pub trait Trait {
type Item<'a> where Self : 'a;
+ #[gat(needs(Item))]
type Iterator<'b> : Iterator<Item=Self::Item<'b>> where Self : 'b;
} Otherwise we could risk a heuristic looking for Thoughts? |
I don't follow the details, but the annotations would be easily manageable. My first gut feeling was that there might arise the need to indicate how deeply chained the GATs are in the trait. These explicit annotations are simpler to provide than that full information. Speaking of nesting: Would the last item in this extended example be annotated like that? #[gat]
pub trait Trait {
type Item<'a> where Self : 'a;
#[gat(needs(Item))]
type Iterator<'b> : Iterator<Item=Self::Item<'b>> where Self : 'b;
#[gat(needs(Iterator, Item)]
type DeepIterator<'c>: Iterator<Item=Self::Iterator<'c>> + Foo<Bar=Self::Item> where Self: 'c;
} (Disclaimer: pure curiosity, my types don't go that deep AFAIR; probably a "this doesn't nest deeper than ..." would even work for me.) |
I think the "chaining" would be automatically figured out, so I suspect that last theoretical example could just have |
Evaluating whether nougat could help get coap-message rid of its nightly wart, I found what appears to be another limitation of nougat that might warrant being pointed out in the list (or maybe fixed if it's easy): GATs do not work when referring to each other in a their required traits' associated types.
This code works with
#![feature(generic_associated_types)]
, but not with#[nougat::gat]
:The relevant error message with macro-backtrace is:
The text was updated successfully, but these errors were encountered: