-
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
[impl Trait] Should we allow impl Trait
after ->
in fn
types or parentheses sugar?
#45994
Comments
How is |
I meant
would desugar to
Of course -- as you righly point out -- if the |
@nikomatsakis I see, thanks for the clarification! |
I've done a bit of hunting, and I think that this is the most appropriate place to bring this up. Allowing I would like to be able to write something like:
See also:
|
@alsuren I found a syntax / way that works: (similar to how Box itself also works with any functions) Would that change your stance that impl Trait is needed? |
@LionsAd Unfortunately, that makes StructWithCallback generic, which means that you can't store it in a vec or hashmap. https://gist.github.com/rust-play/b89d17f00f58f071555339093d76a0a3 If you can't store it in a hashmap, then you can't store it in a routing table, so that's a non-starter for the Gotham use-case. A possible way to avoid needing |
https://gist.github.com/87ab93979d770314e6698a9867d1e7e5 solves this problem using a helper trait. It might be worth waiting to see how https://github.com/gotham-rs/gotham/pull/450/files pans out, but it looks like we don't need |
I have a problem that is related to this issue: https://stackoverflow.com/questions/67458566/how-to-define-a-generic-function-that-takes-a-function-that-converts-a-slice-to. I want to write a generic function that takes a function that iterates a slice in different ways: fn foo(make_iter: impl for<'a> Fn(&'a mut [i32]) -> impl Iterator<Item = &'a mut i32>) {
let mut data = [1, 2, 3, 4];
make_iter(&mut data);
} Currently, this is not possible. Is there any way to work around this issue with stable Rust? The following attempt fails: fn foo<'a, I: Iterator<Item = &'a mut i32>>(make_iter: impl Fn(&'a mut [i32]) -> I) {
let mut data = [1, 2, 3, 4];
make_iter(&mut data);
} Note that I can also use boxed trait object for this, but it requires an extra allocation: fn foo(make_iter: impl for<'a> Fn(&'a mut [i32]) -> Box<dyn Iterator<Item = &'a mut i32> + 'a>) {
let mut data = [1, 2, 3, 4];
make_iter(&mut data);
} |
I came up with one solution: use std::iter::Rev;
use std::slice::IterMut;
trait MakeIter<'a> {
type Iter: Iterator<Item = &'a mut i32>;
fn make_iter(&mut self, slice: &'a mut [i32]) -> Self::Iter;
}
fn foo(mut make_iter: impl for<'a> MakeIter<'a>) {
let mut data = [1, 2, 3, 4];
make_iter.make_iter(&mut data);
}
struct Forward;
impl<'a> MakeIter<'a> for Forward {
type Iter = IterMut<'a, i32>;
fn make_iter(&mut self, slice: &'a mut [i32]) -> Self::Iter {
slice.iter_mut()
}
}
struct Backward;
impl<'a> MakeIter<'a> for Backward {
type Iter = Rev<IterMut<'a, i32>>;
fn make_iter(&mut self, slice: &'a mut [i32]) -> Self::Iter {
slice.iter_mut().rev()
}
}
fn main() {
foo(Forward);
foo(Backward);
} But I am not sure whether it can be simplified. |
RFC 1951 disallowed uses of impl Trait within Fn trait sugar or higher-ranked bounds. For example, the following is disallowed:
This tracking issue exists to discuss -- if we were to allow them -- what semantics they ought to have. Some known concerns around the syntax are:
()
switch from existential to universal quantification and back?impl OtherTrait
to be bound?For consistency, we are disallow
fn(impl SomeTrait) -> impl OtherTrait
anddyn Fn(impl SomeTrait) -> impl OtherTrait
as well. When considering the questions, one should also consider what the meaning would be in those contexts.The text was updated successfully, but these errors were encountered: