-
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
RFC for allowing eliding more type parameters. #1196
Closed
Closed
Changes from 1 commit
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
- Feature Name: prefix_type_param | ||
- Start Date: 2015-07-08 | ||
- RFC PR: (leave this empty) | ||
- Rust Issue: (leave this empty) | ||
|
||
# Summary | ||
|
||
Let specified generic type parameter lists be abbreviated, that is, | ||
`foo::<u8, _>` and `foo::<u8>` are equivalent. | ||
|
||
# Motivation | ||
|
||
There are times when generic functions need to have their type | ||
parameters specified, requiring the use of the `::<...>` | ||
syntax. Before this RFC, doing this would require every type parameter | ||
to have something written, even if it was just `_`. | ||
|
||
```rust | ||
fn foo<T, U, V>() -> T { | ||
// ... | ||
} | ||
|
||
// equivalent: | ||
let x: u8 = foo(); | ||
let y = foo::<u8, _, _>(); | ||
``` | ||
|
||
It is very possible to have APIs that only require a subset of the | ||
type parameters to be specified in the common case (the rest can be | ||
correctly deduced from other information). It is syntactically nice to | ||
allow not writing `_` when it seems "obviously" unnecessary. The above | ||
example could be written: | ||
|
||
```rust | ||
let z = foo::<u8>(); | ||
let w = foo::<u8, _>(); | ||
``` | ||
|
||
One concrete motivation for this is a new design for the | ||
`rand::random` to allow more flexibility. It would have signature: | ||
|
||
```rust | ||
fn random<T: Rand, D: IntoRand<T>>(d: D) -> T | ||
``` | ||
|
||
Generally, the type `D` can be deduced from the call itself, but the | ||
return type requires more information. Either an external type hint | ||
like `let x: u8 = random(..);`, or an explicit function annotation | ||
`random::<u8, _>(..)`. Since it is easily deducable, the second | ||
parameter can usually be left as `_`. It would hence be nicer to be | ||
able to write `random::<u8>`. | ||
|
||
This also makes it easier to add type parameters without downstream | ||
code having to change. | ||
|
||
# Detailed design | ||
|
||
When the compiler handles a type-specified function, instead of | ||
emitting `error: too few type parameters provided: expected N | ||
parameter(s) , found M parameter(s) [E0089]`, it mechanically fills in | ||
the remaining `N - M` parameters with `_`. | ||
|
||
# Drawbacks | ||
|
||
None right now. | ||
|
||
# Alternatives | ||
|
||
- Type ascription may solve much of the motivation for doing this, | ||
since it becomes easier to type-hint things. E.g. the `random` | ||
example can becomes `random(..): u8`. | ||
- Require noting that parameters have been left to inference, | ||
e.g. `random::<u8, ...>`. This defeats much of the syntactic point, | ||
and also means it is less helpful for backwards-compatibility | ||
tricks. | ||
|
||
# Unresolved questions | ||
|
||
None right now. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this alternative is my personal preference (though perhaps with two periods rather than three).
I see why @huonw prefers his proposal, but on the flip side: How do I now specify "these are the exact type parameters, and if another gets added, I want to be told at compile time" ? (Think of it like not having a
_ => ...
match arm...)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(of course one might reasonably point out that we already do not have a way to express "these are the exact type parameters" when dealing with a struct/enum with default type params" ...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have any cases in mind where it's important to know that one is specifying all of the parameters? It seems to me that most cases where adding new parameters requires external adjustment will fail to compile, but I could very very easily be wrong.