Skip to content

Commit ef13af9

Browse files
Reflow
1 parent 24f15c1 commit ef13af9

File tree

1 file changed

+34
-26
lines changed

1 file changed

+34
-26
lines changed

text/3437-implementable-trait-alias.md

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,16 @@ pub trait Frob {
3434
}
3535
```
3636

37-
Most of `frob-lib`'s users will need `Frob::frob`'s return type to be `Send`,
38-
so the library wants to make this common case as painless as possible. But
37+
Most of `frob-lib`'s users will need `Frob::frob`'s return type to be `Send`, so
38+
the library wants to make this common case as painless as possible. But
3939
non-`Send` usage should be supported as well.
4040

4141
### MVP: `trait_variant`
4242

4343
Because Return Type Notation isn't supported yet, `frob-lib` follows the
44-
recommended practice of using the [`trait-variant`](https://docs.rs/trait-variant/)
45-
crate to have `Send` and non-`Send` variants.
44+
recommended practice of using the
45+
[`trait-variant`](https://docs.rs/trait-variant/) crate to have `Send` and
46+
non-`Send` variants.
4647

4748
```rust
4849
//! crate `frob-lib``
@@ -209,7 +210,8 @@ in existence.
209210
## (Speculative) `Async` trait
210211

211212
There has been some discussion about a variant of the `Future` trait with an
212-
`unsafe` poll method, to support structured concurrency ([wg-async design notes](https://rust-lang.github.io/wg-async/vision/roadmap/scopes/capability/variant_async_trait.html)).
213+
`unsafe` poll method, to support structured concurrency ([wg-async design
214+
notes](https://rust-lang.github.io/wg-async/vision/roadmap/scopes/capability/variant_async_trait.html)).
213215
*If* such a change ever happens, then the same "weak"/"strong" relationship will
214216
arise: the safe-to-poll `Future` trait would be a "strong" version of the
215217
unsafe-to-poll `Async`. As the linked design notes explain, there are major
@@ -264,9 +266,11 @@ result is syntactically valid—then the trait alias is implementable.
264266
A trait alias has the following syntax (using the Rust Reference's notation):
265267

266268
> [Visibility](https://doc.rust-lang.org/stable/reference/visibility-and-privacy.html)<sup>?</sup>
267-
> `trait` [IDENTIFIER](https://doc.rust-lang.org/stable/reference/identifiers.html)
269+
> `trait`
270+
> [IDENTIFIER](https://doc.rust-lang.org/stable/reference/identifiers.html)
268271
> [GenericParams](https://doc.rust-lang.org/stable/reference/items/generics.html)<sup>?</sup>
269-
> `=` [TypeParamBounds](https://doc.rust-lang.org/stable/reference/trait-bounds.html)<sup>?</sup>
272+
> `=`
273+
> [TypeParamBounds](https://doc.rust-lang.org/stable/reference/trait-bounds.html)<sup>?</sup>
270274
> [WhereClause](https://doc.rust-lang.org/stable/reference/items/generics.html#where-clauses)<sup>?</sup>
271275
> `;`
272276
@@ -276,9 +280,11 @@ trait alias.
276280
Implementable trait aliases must follow a more restrictive form:
277281

278282
> [Visibility](https://doc.rust-lang.org/stable/reference/visibility-and-privacy.html)<sup>?</sup>
279-
> `trait` [IDENTIFIER](https://doc.rust-lang.org/stable/reference/identifiers.html)
283+
> `trait`
284+
> [IDENTIFIER](https://doc.rust-lang.org/stable/reference/identifiers.html)
280285
> [GenericParams](https://doc.rust-lang.org/stable/reference/items/generics.html)<sup>?</sup>
281-
> `=` [TypePath](https://doc.rust-lang.org/stable/reference/paths.html#paths-in-types)
286+
> `=`
287+
> [TypePath](https://doc.rust-lang.org/stable/reference/paths.html#paths-in-types)
282288
> [WhereClause](https://doc.rust-lang.org/stable/reference/items/generics.html#where-clauses)<sup>?</sup>
283289
> `;`
284290
@@ -447,9 +453,9 @@ let _: IntIter<Item = u32> = [1_u32].into_iter(); // `Item = u32` is redundant,
447453
# Drawbacks
448454

449455
- The syntactic distance between implementable and non-implementable aliases is
450-
short, which might confuse users. In particular, the fact that
451-
`trait Foo = Bar + Send;` means something different than
452-
`trait Foo = Bar where Self: Send;` will likely be surprising to many.
456+
short, which might confuse users. In particular, the fact that `trait Foo =
457+
Bar + Send;` means something different than `trait Foo = Bar where Self:
458+
Send;` will likely be surprising to many.
453459
- Adds complexity to the language, which might surprise or confuse users.
454460
- Many of the motivating use-cases involve language features that are not yet
455461
stable, or even merely speculative. More experience with those features might
@@ -474,9 +480,10 @@ let _: IntIter<Item = u32> = [1_u32].into_iter(); // `Item = u32` is redundant,
474480
- It could also make it less obvious which trait is being implemented, versus
475481
required; are we implementing `Bar`, `Send`, or both?
476482
- Again, user feedback could help make this decision.
477-
- Another option is to require an attribute on implementable aliases; e.g. `#[implementable] trait Foo = ...`.
478-
This would make the otherwise-subtle implementability rules more explicit, at
479-
the cost of cluttering user code and the attribute namespace.
483+
- Another option is to require an attribute on implementable aliases; e.g.
484+
`#[implementable] trait Foo = ...`. This would make the otherwise-subtle
485+
implementability rules more explicit, at the cost of cluttering user code and
486+
the attribute namespace.
480487
- A previous version of this RFC required generic parameters of implementable
481488
trait aliases to be used as generic parameters of the alias's primary trait.
482489
This restriction was meant to avoid surprising errors:
@@ -517,9 +524,9 @@ even at the risk of potential confusion.
517524

518525
# Unresolved questions
519526

520-
- How does `rustdoc` render these? Consider the `Frob` example—ideally,
521-
`Frob` should be emphasized compared to `LocalFrob`, but it's not clear
522-
how that would work.
527+
- How does `rustdoc` render these? Consider the `Frob` example—ideally, `Frob`
528+
should be emphasized compared to `LocalFrob`, but it's not clear how that
529+
would work.
523530

524531
# Future possibilities
525532

@@ -557,7 +564,8 @@ impl Foo for Stu {
557564
Such a feature could be useful when a trait has multiple items and you want to
558565
split it in two.
559566

560-
However, there are some issues to resolve. Most glaring is the risk of name collisions:
567+
However, there are some issues to resolve. Most glaring is the risk of name
568+
collisions:
561569

562570
```rust
563571
trait A {
@@ -624,10 +632,9 @@ pub trait Frobnicate = FlexibleFrobnicate<Output = Option<Self::Item>> {
624632
}
625633
```
626634

627-
`impl` blocks should be allowed to omit associated items that are
628-
"uniquely constrained" by other such items. Such a capability would be useful
629-
even outside the context of trait aliases, for example when implementing
630-
`IntoIterator`:
635+
`impl` blocks should be allowed to omit associated items that are "uniquely
636+
constrained" by other such items. Such a capability would be useful even outside
637+
the context of trait aliases, for example when implementing `IntoIterator`:
631638

632639
```rust
633640
struct Iter;
@@ -672,9 +679,10 @@ trait ResultIterator = Iterator<Item = Result<Self::Ok, Self::Err>> {
672679
```
673680

674681
In the context of the above example, a `T: ResultIterator` bound would mean
675-
"there exist unique types `Ok` and `Err` such that
676-
`T: Iterator<Item = Result<Ok, Err>>` holds". Current Rust provides no mechanism
677-
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).
682+
"there exist unique types `Ok` and `Err` such that `T: Iterator<Item =
683+
Result<Ok, Err>>` holds". Current Rust provides no mechanism for expressing a
684+
bound like that; you need a separate trait, like
685+
[`TryFuture`](https://docs.rs/futures-core/latest/futures_core/future/trait.TryFuture.html).
678686

679687
This feature could even allow GATification of `Iterator` (or `FnMut`, etc)
680688
without variance bounds:

0 commit comments

Comments
 (0)