Bound Items
Summary
Targets the bounding futures challenge.
This is a series of smaller changes (see detailed design), with the goal of allowing the end user to name the bound described in the challenge text in this way (i'll let the code speak for itself):
#![allow(unused)] fn main() { pub trait AsyncIterator { type Item; async fn next(&mut self) -> Option<Self::Item>; } pub async fn start_writing_logs<F>( logs: F ) where IsThreadSafeIterator<F>, F: 'static { // IsThreadSafeIterator is defined below todo!() } pub bound IsThreadSafeAsyncIterator<T> { T: AsyncIterator + Send, // Add a `fn` keyword here to refer to the type of associated function. <T as AsyncIterator>::fn next: SimpleFnOnceWithSendOutput, // Use `*` to refer to potentially long list of all associated functions. // this is useful in certain cases. <T as AsyncIterator>::fn *: SimpleFnOnceWithSendOutput, } }
Detailed design
I'm not good at naming things, and all names and identifiers are subject to bikeshedding.
-
Bound Item(Language construct). Allow user to name a combination of bounds. No
Self
allowed here. Could replace thetrait_alias
language feature. Improve ergonomics of many existing code if used properly.I'm hesitant on which of
PascalCase
,snake_case
, orUPPER_CASE
should be used for this naming though. -
Syntax for refering to the type of a associated item in path. Currently using
fn
keyword. Can expand toconst
andtype
keywords if needed. Turbofish might be involved if the assoc item is generic. -
SimpleFnOnce
trait (Language item). A function can only accept one set of arguments, so all functions and closures shall implement this, while user-defined callable types doesn't have to. This is used for reasoning about the output parameters of associated functions.#![allow(unused)] fn main() { pub trait SimpleFnOnce: FnOnce<Self::Arg> { type Arg; } }
-
SimpleFnOnceWithSendOutput
trait (Lib construct or user-defined).#![allow(unused)] fn main() { pub trait SimpleFnOnceWithSendOutput : SimpleFnOnce where Self::Output: Send {} impl<T> SimpleFnOnceWithSendOutput for T where T:SimpleFnOnce, T::Output: Send {} }
What's great about this
- Absolutely minimal type system changes.
- Quite easy to learn. (Name it and use the name)
- Easy to write library documentation, and give examples.
What's not so great
- New syntax item constructs. Three parsers (rustc, ra, syn) needs to change to support this.
- Very verbose code writing style. Many more lines of code.
- Will become part of library API in many cases.