-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Allow impl Trait
in more contexts
#1879
Comments
For local variables, is there a use-case for using let x: &Foo = &bar(); |
What if I want to move my value into `x`, instead of borrowing it?
|
@spinda, |
I may want to provide an explicit type annotation to clear up some ambiguity, for example, a type parameter that can't be inferred. Really, I would like to remove as much special-casing of where |
@spinda Keep in mind the semantics can differ a lot between those positions. And this always worked: fn bar() -> Option<impl Foo> { } |
@eddyb So it does, thanks. I was under the impression that only |
Couldn't all locations that so far are compilation failures due to |
As an alternative, one could use an associated output type for functions, ala I'm nervous about taking That said, there are certainly situations where you can simplify presentation using that interpretation. In particular, you can make users view your tiers of type parameters in a two tiered way, as happens with several
|
My understanding of impl Trait was that it has fundamentally different semantics from type parameters, namely: the concrete type that a type parameter represents is determined by the function's call site, while the concrete type that an impl Trait represents is decided by the function's implementation. Given that, it seems nonsensical to put "impl Trait" in all of these other parts of the grammar as if it was merely syntactic sugar for ordinary type parameters. For instance, under this RFC, would the desugaring of |
I suppose your
because now the I imagine this |
|
I think If I understand, In particular, anything you'd do with |
We could use
|
It's unclear if
vs
|
Why
|
I don't think it should be done for struct fields, because you cannot say the type from the declaration anymore. Additionally, you can easily make your struct generic over In the above example it does not make much sense to store the same closure multiple times. What you want instead is a heterogeneous Vector using |
You could store the same closure with different captures using |
how would I do following without
If I had a local vector, it also would not have to contain boxes of traits, |
By having a struct struct Action {
c: i32,
inc: i32,
}
impl Action {
fn execute(&mut self) {
self.c += inc;
println!("{}", self.c);
}
} It's of course more code, but if you have a Vec<impl Trait> you do not know what type it is by looking at the declaration (it's the same as for constants; using it different locally should not change the signature of a public item). Furthermore, you can never use the concrete type, which means you will have an
I'm not sure if I understand you correctly. Is the following what you want to do? let mut v = Vec::new();
v.push(|| do_whatever_you_want()); |
Yes, your example is what I mean. This is only possivle with local variables, not when I need to specify a type. And yes, it's possile for every closure to be imlemented as structs with some call method, but don't closures exist to allow skipping to write such code? |
@porky11 We could theoretically infer much more than we do: function return types, lifetimes, globals' types... However, if we do that, it becomes very difficult to argue about the code.
I guess they exist for some ergonomic handling like using iterator adapters where it would not make sense to explicitly declare a function or a struct for them. I somehow agree that this limits the flexibility of a closure, but I really prefer to have the full type information given (just imagine you have a function |
Closing as we've already accepted RFCs for this (well... |
Currently
impl Trait
is only allowed as the return type of a free-standing functions and inherent methods. I would like to see it opened to a few more positions.Local variable signatures
can already be simulated by:
Also,
If
bar
returnsOption<Baz>
,Baz
would be checked for an implementation ofFoo
.Parameters of free-standing functions and methods
can be equivalent to:
Furthermore,
can be equivalent to:
This cuts down a bit on boilerplate.
Other positions in return types of free-standing functions and methodsfn bar() -> Option<impl Foo> { }
The text was updated successfully, but these errors were encountered: