-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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: Consider supporting function return type deduction #10448
Comments
FWIW, it's only 1000x slower with a vector iterator and is more reasonable with something like an unbuffered line iterator |
@huonw mentioned that
It would be uncomfortable enough for a human to write so it wouldn't get much use, but it'd be simple for a macro/syntax extension to duplicate the fn body into both the type and the actual fn body. |
C++11 added |
FWIW, Rust has nicer macros than C++, so it is possible to write something like ret_type_infer!(fn foo(x: int, y: int) -> _ { <body> })
// expands to
fn foo(x: int, y: int) -> typeof({ <body> }) { <body> } (For this, |
It still wouldn't work for unboxed closures. |
It could, in theory. If the type of an unboxed closure depended only on the AST/types (ignoring (This is likely to be unreasonably complicated to achieve, of course.) |
Adding |
OTOH, I wouldn't be opposed to ABI-breaking features if it wasn't allowed to mark them |
I suspect associated items could alleviate some of these cases, though probably not all of them. E.g. instead of writing: fn foo<'a>(v: &'a [int]) -> std::iter::Rev<std::vec::Items<'a, int>> {
v.iter().rev()
} (which require you have knowledge of the names of implementing structs within fn foo<'a>(v: &'a [int]) -> std::vec::Slice<'a, int>::Iter::Rev {
v.iter().rev()
} and in practice since you'll be fn foo<'a>(v: &'a [int]) -> Slice<'a, int>::Iter::Rev {
v.iter().rev()
} Like I said at the outset, it doesn't handle all cases cleanly (e.g. the I actually suspect the ideal thing could be a hypothetical statically-resolved existential syntax like fn foo<'a>(v: &'a [int]) -> <I:Iter> I {
v.iter().rev()
} that is the dual to the universal parameterization syntax that one sees with But no need to work on any of this until after 1.0 I think. |
@glaebhoerl ah, thanks for the link. I suppose my suggestion is indeed a kind of type-inference, though my mental model remains that of a statically-resolved existential (probably because I see the
|
@pnkfelix The acid test here is:
Should we allow this? We know the result of I've actually come around to prefer the latter: this means that from outside
This reads to me as a universal: Incidentally:
This happens to be incorrect as written, because information about the lifetime is lost in the result. Just as with boxed trait objects, you would have to write |
From the viewpoint of the caller of Anyway, you are correct, my example did not illustrate an instance where one would need explicit binding of an actual name. One needs binding if one wants to use the same existentially-bound type variable multiple times in the type expression, like in the following, which returns a tuple where both
(Is it useful? I don't know yet. I suppose the implicit point of your message is that our existing syntax for existential types a la trait objects does not let one express something like the above, and therefore it is unlikely to be of use.) |
I think my implicit point was that explicit existential syntax, while potentially useful, is orthogonal to this feature. |
tangential comment,having perhaps |
I've written a formal RFC: rust-lang/rfcs#105 |
Keeping around an issue here isn't necessary because this isn't backwards incompatible or actionable. A proposal needs to be accepted through the RFC process. |
Add new `redundant_async_block` lint Fixes rust-lang#10444 changelog: [`redundant_async_block`]: new lint to detect `async { future.await }`
I had a brief chat on IRC today about adding support for deducing the function return type. I realize we decided against doing this a couple years ago, but I think it's worth revisiting in light of iterators. One of the challenges with our iterators is that the types of complex iterators are unwieldy. For example, here's the type of chaining two vecs together:
While we can generally rely on type inference inside a function, things get really messy once we try to return an iterator from a function. One way to avoid this complicated type is to box of the iterators inside a
~Iterator<int>
, but according to @thestinger, this is ~1000x slower than with a monomorphized iterator. Having return type deduction would make it much easier to pass around iterators.This would also be really handy for macros and syntax extensions. For example, we could convert the serialize.rs over to iterators without needing generators (#9145).
This has been proposed for (C++14)[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3638.html].
@cmr had an argument against this. He felt that adding return type deduction would make it that much easier to break ABIs.
The text was updated successfully, but these errors were encountered: