-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[impl Trait] Should we allow impl Trait
after ->
in fn
types or parentheses sugar?
#45994
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
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: