diff --git a/design.md b/design.md new file mode 100644 index 0000000..edddc94 --- /dev/null +++ b/design.md @@ -0,0 +1,177 @@ +- Name: `keyword-generic-effect-clause` +- Proposed by: [Caio](@CaioOliveira793) +- Original proposal (optional): N/A + +# Design + + + +## base (reference) + + + +```rust +/// A trimmed-down version of the `std::Iterator` trait. +pub trait Iterator { + type Item; + fn next(&mut self) -> Option; + fn size_hint(&self) -> (usize, Option); +} + +/// An adaptation of `Iterator::find` to a free-function +pub fn find(iter: &mut I, predicate: P) -> Option +where + I: Iterator + Sized, + P: FnMut(&T) -> bool; +``` + +## always async + + + +```rust +pub trait Iterator +where + effect: async +{ + type Item; + + // opt-in for a async effect + fn next(&mut self) -> Option + where + effect: async; + + // the size_hint is left unchanged, since the effect is opt-in + fn size_hint(&self) -> (usize, Option); +} + +// the `effect` generic indicates that this function is generic +// over keywords +pub fn find(iter: &mut I, predicate: P) -> Option +where + effect: async, + // iterator effect **must** be async + I: Iterator + // a short version is also possible + // I: Iterator + Sized, + I: Iterator + Sized, + P: FnMut(&T) -> bool; +``` + +## maybe async + + + +```rust +pub trait Iterator +where + effect: ?async +{ + type Item; + + fn next(&mut self) -> Option + where + effect: ?async; + + fn size_hint(&self) -> (usize, Option); +} + +pub fn find(iter: &mut I, predicate: P) -> Option +where + effect: ?async, + // iterator effect is be **maybe** async + I: Iterator + I: Iterator + Sized, + P: FnMut(&T) -> bool; +``` + +## generic over all modifier keywords + + + +```rust +pub trait Iterator +where + // in order to be generic over all keywords the effect clause must specify all the keywords available + effect: ?async + ?const +{ + type Item; + + fn next(&mut self) -> Option + where + effect: ?async + ?const; + + // functions without effect anotatios follows the same rules as if + // the trait wasn't generic over a keyword + fn size_hint(&self) -> (usize, Option); + + // ... or possibilly, they could restrict the keywords allowed + fn size_hint(&self) -> (usize, Option) + where + effect: !async + ?const; +} + +pub fn find(iter: &mut I, predicate: P) -> Option +where + effect: ?async + ?const, + I: Iterator + Sized, + P: FnMut(&T) -> bool; +``` + +# Notes + +## Compatiablity + +compatible with [associated type bounds](https://github.com/rust-lang/rust/issues/52662): + +```rust +pub fn find(iter: &mut I, predicate: P) -> Option +where + effect: ?async + ?const, + // the choice over ":" or "=" is open + I: Iterator, + // or + ::effect: ?async + ?const, + // or + I: Iterator, + I: Iterator + Sized, + P: FnMut(&T) -> bool; +``` + +is also compatible with [return type notation](https://smallcultfollowing.com/babysteps/blog/2023/02/13/return-type-notation-send-bounds-part-2/) + +```rust +pub trait HealthCheck +where + effect: async +{ + fn check(&mut self, server: Server) + where + effect: async; +} + +fn start_health_check(health_check: H, server: Server) +where + effect: async, + H: HealthCheck + Send + 'static, +``` + +## explicit all modifiers keywords + +The syntax does not give shortans for specifing all modifiers at once. + +Positive + +- explicit +- backwards compatible to introduce new keywords +- extendable + +Negative + +- cumbersome to declare all keywords + +