It’s finally coming! We’re in the home stretch for landing the long-awaited impl Trait feature. impl Trait allows functions to accept and return values of unnamed types that implement some trait.
Many longstanding bugs and ICEs have been fixed, and final syntax details are nearly resolved. With that in mind, we need help testing and experimenting with the feature before stabilizing. Please consider taking a moment or two to play around with the feature, perhaps by converting existing Rust libraries or projects to use impl Trait. To try it yourself, just update to the latest nightly and put #![feature(conservative_impl_trait, universal_impl_trait)] at the top of your crate, like this:
If you have any question, concerns, or feedback about the feature, please message me on IRC, Gitter, or open an issue on rust-lang/rust and cc me (cramertj).
Awesome! I can add it as a gated feature for one of my projects where I use Box. I’ll do some speed tests as well to see if this helps with the dynamic dispatch.
impl Trait isn’t currently allowed in Fn syntax, no. We definitely want to support it eventually, but the final design is not yet resolved. It’s possible that we might want impl Trait in Fn() argument position to be sugar for type-HRTB (e.g. Fn(impl Debug) could desugar to for<T: Debug> Fn(T)). Type-HRTB doesn’t have an RFC and hasn’t been implemented, so there’s still a ways to go before we see anything like that on stable.
Is there a version of the calendar example somewhere implemented using impl trait ? That’s actually what motivated its development (@eddyb 's calendar-driven-development!) and I’d like to see how it solves the problem that it was supposed to solve.
I’m excited to see this feature land, but I’m bemused by the example showing use of impl trait in argument position. This looks to be just be a third way of writing a trait bound, and one that would require rewriting to something totally syntactically different if you ever needed to name the parameter type. Have I misunderstood what this new syntax does?
This looks to be just be a third way of writing a trait bound, and one that would require rewriting to something totally syntactically different if you ever needed to name the parameter type. Have I misunderstood what this new syntax does?
Argument-position impl Trait is a shorthand way to say "I want to take an input parameter of any type that implements Trait". As you said, fn foo(x: impl Trait) { ... } desugars roughly to fn foo<T: Trait>(x: T) { ... }. This change offers primarily ergonomic and learnability benefits-- for more on the motivation, see RFC 1951.
I would have found it more confusing when learning Rust if there was another, less powerful, very different looking, way of writing the same thing. It also feels like needless code churn - there’s no point in new syntax if no-one uses it, and if using it is encouraged then a load of existing code (and docs, blog posts, forum answers…) becomes “bad form” for using the other two of the three syntactic forms for the same thing.
Edit: this sounds more hostile than intended, largely due to terseness from typing it on a phone. I’ll not derail this thread any further - is there a proper place to raise this sort of objection or has that ship sailed?
looks pretty good… There’s a natural progression to it =)
It’s also a matter of ergonomics, with anonymity, you don’t have to have type variables on one side and parameters after when you just want a value that satisfies a bound.
Does this include allowing impl Trait to be used in trait items? (IIRC that was an RFC that was accepted, right?) Also how does impl Trait interact as a type parameter in signatures? e.g. Could fn to_sql<W: Write>(&self, out: &mut Output<W, DB>>) be rewritten as fn to_sql(&self, out: &mut Output<impl Write, DB>)?
Does this include allowing impl Trait to be used in trait items? (IIRC that was an RFC that was accepted, right?)
There hasn't been an RFC yet for impl Trait in trait items. RFC 2071 allows you to accomplish something similar, but that RFC isn't yet implemented.
Also how does impl Trait interact as a type parameter in signatures?
Currently, using impl Trait makes it an error to manually specify type parameters for a function (a la collect::<Vec<_>>). This is a conservative restriction that we will almost certainly lift as we get more experience with the feature. IMO the most likely course of option is that impl Trait type parameters don't appear in parameter lists at all, but that would make it a breaking change to make the transition in your example.
It doesn’t compile because the compiler doesn’t know that the iterator it returns is an iterator of i32s, just that its an iterator. So outside of that function, the compiler has no idea what type cnt is.
You can specify that its an iterator of i32s, and then it will work
fn running_count(iter: impl Iterator<Item = i32>) -> impl Iterator<Item = i32> { iter }
fn main() {
for cnt in running_count(1..10) {
println!("{}", cnt);
}
}
``
It would be great if impl Trait in argument position could be not only a syntactic sugar, but add something more useful to the language. If impl Trait would introduce hidden type parameter, send3_v1 and send3_v2 could be equivalent, but send3_v2 implementation is more straightforward to write: