Skip to content

Commit b0267f8

Browse files
committed
Add API evolution to motivation.
1 parent a129cb5 commit b0267f8

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

text/0000-prefix-type-params.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,38 @@ let z = foo::<u8>();
3636
let w = foo::<u8, _>();
3737
```
3838

39-
One concrete motivation for this is a new design for the
39+
A major motivation for this is it allows generalising a function by
40+
adding new (usually-inferrable) type parameters to a function, without
41+
breaking users who already specify existing parameters. This makes the
42+
API evolution story for Rust code more flexible. For example, consider
43+
these two definitions of `foo`:
44+
45+
``` rust
46+
fn foo<T>(x: &str) { ... }
47+
fn foo<T, U>(x: U) { ... }
48+
```
49+
50+
A library version `1.0.0` might include the first `foo`, and users
51+
would call it like `foo::<i32>("bar")`. Later, it is
52+
realised that `foo` can be generalised to the second one (presumably
53+
with some trait bounds on `U`, in practice), and so `1.1.0` is
54+
released with the new definition, which would unfortunately break our
55+
existing caller, with an message like:
56+
57+
```
58+
error: too few type parameters provided: expected 2 parameters, found 1 parameter [E0089]
59+
foo::<i32>("bar")
60+
^~~~~~~~~~
61+
```
62+
63+
This case can be completely addressed by instead calling `foo::<i32,
64+
_>`, letting the compiler do all the work to infer `U`. This RFC
65+
allows this this `_` insertion to happen implicitly, and so the
66+
`1.1.0` release with its new definition of `foo` would not break the
67+
`foo::<i32>("bar")` call at all: it would just continue to work.
68+
69+
70+
Another concrete motivation for this is a new design for the
4071
`rand::random` to allow more flexibility. It would have signature:
4172

4273
```rust

0 commit comments

Comments
 (0)