@@ -36,7 +36,38 @@ let z = foo::<u8>();
36
36
let w = foo :: <u8 , _ >();
37
37
```
38
38
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
40
71
` rand::random ` to allow more flexibility. It would have signature:
41
72
42
73
``` rust
0 commit comments