Skip to content

Commit 601cc9c

Browse files
Future possibility: trait aliases constrained by their associated items
1 parent b027df1 commit 601cc9c

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

text/3437-implementable-trait-alias.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,54 @@ impl IntoIterator for IntoIter {
632632
}
633633
```
634634

635+
### Trait aliases constrained by their associated items
636+
637+
If trait aliases with associated items are additionally allowed to refer to
638+
those items from the definition of the alias itself, it would be possible to
639+
express certain kinds of trait bounds that current `where` clauses do not
640+
support.
641+
642+
For example:
643+
644+
```rust
645+
/// An `Iterator` that yields `Result`s.
646+
trait ResultIterator = Iterator<Item = Result<Self::Ok, Self::Err>> {
647+
type Ok;
648+
type Err;
649+
}
650+
```
651+
652+
In the context of the above example, a `T: ResultIterator` bound would mean
653+
"there exist unique types `Ok` and `Err` such that
654+
`T: Iterator<Item = Result<Ok, Err>>` holds". Current Rust provides no mechanism
655+
for expressing a bound like that; you need a separate trait, like [`TryFuture`](https://docs.rs/futures-core/latest/futures_core/future/trait.TryFuture.html).
656+
657+
This feature could even allow GATification of `Iterator` (or `FnMut`, etc)
658+
without variance bounds:
659+
660+
```rust
661+
pub trait LendingIterator {
662+
type LentItem<'a>
663+
where
664+
Self: 'a;
665+
666+
fn next<'a>(&'a mut self) -> Option<Self::LentItem<'a>>;
667+
}
668+
669+
// `T: Iterator` means
670+
// "there exists a unique type `Item` such that
671+
// `T: LendingIterator where for<'a> Self::LentItem<'a> = Item`"
672+
// (which holds iff `Self::LentItem<'a>` is bivariant in `'a`).
673+
pub trait Iterator = LendingIterator
674+
where
675+
// Still need to solve implied `'static` bound problem
676+
// (https://blog.rust-lang.org/2022/10/28/gats-stabilization.html#implied-static-requirement-from-higher-ranked-trait-bounds)
677+
for<'a> Self::LentItem<'a> = Self::Item,
678+
{
679+
type Item;
680+
}
681+
```
682+
635683
### Name conflicts
636684

637685
One wrinkle with the above scheme, is that it is possible for the trait being

0 commit comments

Comments
 (0)