-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: implicit generic function arguments with bounds #11196
Comments
Besides from the obvious ABI compatibility issue, this proposal severely limits the user's ability to selectively disable monomorphization. For example, if a function |
The proposal is by no means set in stone, but here's a quick way of disabling monomorphization: fn f_virtual<T: Trait>(x: &T) {
f(x as &Trait)
}
// Maybe this attribute could disable monomorphization by itself?
// Or we could have another attribute, like #[virtual_trait_args].
#[inline(never)]
fn f(x: &Trait) {...} |
I'd rather have a general solution that interacts well with the rest of the language rather than a special case one (note how T, U, V remain where they are!) that doesn't. I'd look at what other languages with traits/concepts/etc do and see if it's any better. E.g. in D it is also more syntactically light to use dynamic dispatch, and yet most use static dispatch anyway. Here is what a complicated function signature with type constraints looks like in D: void fill(Range1, Range2)(Range1 range, Range2 filler)
if (isInputRange!Range1
&& (isForwardRange!Range2
|| (isInputRange!Range2 && isInfinite!Range2))
&& is(typeof(Range1.init.front = Range2.init.front)))
{
} I.e. the type constraints (the code that starts after the fn map2fn<T, U, V, F1, F2>(x: T, f1: F1, f2: F2) -> V
where<F1: Fn<U, V>, F2: Fn<U, V>>
{
f2(f1(x))
}
// OR
fn map2fn(x: T, f1: F1, f2: F2) -> V
where<T, U, V, F1: Fn<U, V>, F2: Fn<U, V>>
{
f2(f1(x))
} |
@eddyb, re virtualisation, I believe @lifthrasiir is just pointing out that the proposed syntax only works for traits not contained in any pointers, specifically (and most importantly), you can't write |
Even without the speculation about |
I've now written an RFC that includes something like this proposal: rust-lang/rfcs#105 |
This issue has been moved to the RFCs repo: rust-lang/rfcs#302 |
[significant_drop_tightening] Fix rust-lang#11189 Fix rust-lang#11189 ``` changelog: FP: [`significant_drop_tightening`]: Consider tuples in drop calls ```
Using generic functions with trait bounds results in efficient code generation, at the cost of syntactic simplicity (compared to using trait objects).
Consider this snippet:
Now with trait bounds moved to argument types (creating implicit generic type parameters):
Note that this would be limited to values as references or pointers would conflict with current syntax for trait objects.
However, optimizing
&Trait
in an argument type (or even a structure field? there is room for discussion here) to a generic (<T: Trait> ... &T
) wouldn't cause any serious issues AFAICT.And it would mean we can make the closure syntax be sugar for
&Fn
without losing backwards compatibility while allowing compile-time monomorphization.The text was updated successfully, but these errors were encountered: