Hi,
I stumbled upon C++ Concepts Lite presentation, and saw some interesting things which are missing from Rust, but can be quite useful. I mean, 'weak' type bounds and bounds-based overload.
Here are main theses:
-
You can do blanket impl for some trait with overlapping bounds if those bounds form totally ordered subtyping hierarchy
trait Actor {
fn action(&self);
}
impl Actor for T {
fn action(&self) { /* some default action / }
}
impl<T: Iterator> Actor for T {
fn action(&self) { / some action for iterator / }
}
impl<T: ExactSizeIterator> Actor for T {
fn action(&self) { / action for exact size iterator */ }
}
...
fn do_stuff<T: Actor>(actor: &T) {
actor.action();
}
The main idea is to call some implementation based on what type T actually supports.
2. Constraints on type are 'weak', i.e. they allow overloaded function from (1) to check for type properties not available to outer function:
fn do_outer_stuff<T: OtherActor>(actor: &T) {
...
do_stuff(actor);
...
}
Here, do_outer_stuff
can only do what OtherActor
provides; but do_stuff can be more specific.
3. p.1 can have some nice sugar:
fn do_stuff<T>(actor: &T) { ... }
fn do_stuff<T: Iterator>(actor: &T) { ... }
fn do_stuff<T: ExactSizeIterator>(actor: &T) { ... }
some constraints can apply here, like overload only by a single argument, and constraints should form total ordering
To sum up, this looks to play nicely with the latest post from Aaron Turon: Resurrecting impl Trait · Aaron Turon, in particular the first proposed approach with type elision. This is effectively the same - a constrained type T remains the same, we're only restricted to the operations we specified in constraints. But some other function can apply its own resolution.
I welcome to discuss this idea. Would be nice to see core team member's opinion.
Thanks