Description
The draft RFC about named function types mentions that impl Traits
in a function argument position could be changed to be a "late-bound" part of the function type, so that the non-generic type would be settled on the function call-site, per-call basis.
Rust already has a feature called "higher-ranked trait bounds", that enables functions to have arguments with lifetimes that are a "late-bound" part of the type; that is, the function is guaranteed to work with arguments of any lifetime. Because lifetimes can always be erased, unlike other generics, this is just a type-level construct that doesn't need monomorphisation (and the lifetime erasure will make it work even with function pointers).
If a named function types feature is realised and impl Traits
in function arguments are changed to behave as "late-bound", does that mean, that Rust gains new capabilities to express higher-ranked types? If the impl Traits
in function argument position are considered late-bound, the following may become possible:
struct Container<F: Fn(impl Debug)> {
f: F,
}
fn inner(input: impl Debug) {
}
fn main() {
let container = Container { f: inner };
(container.f)(1u32); // Different argument types here...
(container.f)(1i32); // ...and here
}
To me, this looks remarkably similar to this hypothetical use of the for<_>
syntax:
struct Container<F> where for<D: Debug> F: Fn(D) {
f: F,
}
fn inner<D: Debug>(input: D) {
}
fn main() {
let container = Container { f: inner };
(container.f)(1u32); // Different argument types here...
(container.f)(1i32); // ...and here
}
If late-bound argument types expose new functionality that is in some form equivalent to higher-ranked types, I expect the RFC to discuss about that, and consider the connection to the for<_>
syntax.