You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/3437-implementable-trait-alias.md
+42-1Lines changed: 42 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -157,7 +157,7 @@ so this change would break every `impl Iterator` block in existence.
157
157
158
158
## Speculative example: `Async` trait
159
159
160
-
There has been some discussion about a variant of the `Future` trait with an `unsafe` poll method, to support structured concurrency ([here](https://rust-lang.github.io/wg-async/vision/roadmap/scopes/capability/variant_async_trait.html) for example). *If* such a change ever happens, then the same "weak"/"strong" relationship will arise: the safe-to-poll `Future` trait would be a "strong" version of the unsafe-to-poll `Async`. As the linked design notes explain, there are major problems with expressing this relationship in today's Rust.
160
+
There has been some discussion about a variant of the `Future` trait with an `unsafe` poll method, to support structured concurrency ([here](https://rust-lang.github.io/wg-async/vision/roadmap/scopes/capability/variant_async_trait.html) for example). *If* such a change ever happens, then the same "weak"/"strong" relationship will arise: the safe-to-poll `Future` trait would be a "strong" version of the unsafe-to-poll `Async`. As the linked design notes explain, there are major problems with expressing that relationship in today's Rust.
161
161
162
162
# Guide-level explanation
163
163
@@ -323,6 +323,47 @@ More experience with those features might unearth better alternatives.
323
323
(For example, `trait Foo = Bar + Send;` could be made implementable). However, this would arguably make implementability rules less intuitive, as the symmetry with `impl` blocks would be broken.
324
324
- Another possibility is to require an attribute on implmenentable aliase; e.g. `#[implementable] trait Foo = ...`. This would make the otherwise-subtle implementability rules explicit, but at the cost of cluttering the attribute namespace and adding more complexity to the language.
325
325
326
+
## What about combining multiple prtimary traits, and their items, into one impl block?
327
+
328
+
It's possible to imagine an extension of this proposal, that allows trait aliases to be implementable even if they have multiple primary traits. For example:
329
+
330
+
```rust
331
+
traitFoo=Clone+PartialEq;
332
+
333
+
structStu;
334
+
335
+
implFooforStu {
336
+
fnclone(&self) ->Self {
337
+
Stu
338
+
}
339
+
340
+
fneq(&self, other:&Self) ->bool {
341
+
true
342
+
}
343
+
}
344
+
```
345
+
346
+
Such a feature could be useful when a trait has multiple items and you want to split it in two.
347
+
348
+
However, there are some issues. Most glaring is the risk of name collisions:
349
+
350
+
```rust
351
+
traitA {
352
+
fnfoo();
353
+
}
354
+
355
+
traitB {
356
+
fnfoo();
357
+
}
358
+
359
+
// How would you write an `impl` block for this?
360
+
traitC=A+B;
361
+
```
362
+
363
+
Such a feature could also make it harder to find the declaration of a trait item from its implementation, especially if IDE "go to definition" is not available. One would need to first find the trait alias definition, and then look through every primary trait to find the item. (However, given the current situation with postfix method call syntax, maybe this is an acceptable tradeoff.)
364
+
365
+
Perhaps a more narrowly tailored version of this extension, in which both subtrait and supertrait explicitly opt-in to support sharing an `impl` block with one another, would satisfy the backward-compatibility use-case while avoiding the above issues. I think exploring that is best left to a future RFC.
0 commit comments