|
| 1 | +- Feature Name: deprecate_anonymous_parameters |
| 2 | +- Start Date: 2016-07-19 |
| 3 | +- RFC PR: (leave this empty) |
| 4 | +- Rust Issue: (leave this empty) |
| 5 | + |
| 6 | +# Summary |
| 7 | +[summary]: #summary |
| 8 | + |
| 9 | +Currently Rust allows anonymous parameters in trait methods: |
| 10 | + |
| 11 | +```Rust |
| 12 | +trait T { |
| 13 | + fn foo(i32); |
| 14 | + |
| 15 | + fn bar_with_default_impl(String, String) { |
| 16 | + |
| 17 | + } |
| 18 | +} |
| 19 | +``` |
| 20 | + |
| 21 | +This RFC proposes to deprecate this syntax. This RFC intentionally does not |
| 22 | +propose to remove this syntax. |
| 23 | + |
| 24 | +# Motivation |
| 25 | +[motivation]: #motivation |
| 26 | + |
| 27 | +Anonymous parameters are a [historic accident]. They do not pose any |
| 28 | +significant problems, but lead to a number of annoyances. |
| 29 | + |
| 30 | +1. Surprising pattern syntax in traits |
| 31 | + |
| 32 | + ```Rust |
| 33 | + trait T { |
| 34 | + fn foo(x: i32); // Ok |
| 35 | + fn bar(&x: &i32); // Ok |
| 36 | + fn baz(&&x: &&i32); // Ok |
| 37 | + fn quux(&&&x: &&&i32); // Syntax error |
| 38 | + } |
| 39 | + ``` |
| 40 | + |
| 41 | + That is, patterns more complex than `_, foo, &foo, &&foo, mut foo` are |
| 42 | + forbidden. |
| 43 | + |
| 44 | +2. Inconsistency between default implementations in traits and implementations |
| 45 | + in impl blocks |
| 46 | + |
| 47 | + ```Rust |
| 48 | + trait T { |
| 49 | + fn foo((x, y): (usize, usize)) { // Syntax error |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + impl T for S { |
| 54 | + fn foo((x, y): (usize, usize)) { // Ok |
| 55 | + } |
| 56 | + } |
| 57 | + ``` |
| 58 | +3. Inconsistency between method declarations in traits and in extern blocks |
| 59 | + |
| 60 | + ```Rust |
| 61 | + trait T { |
| 62 | + fn foo(i32); // Ok |
| 63 | + } |
| 64 | + |
| 65 | + extern "C" { |
| 66 | + fn foo(i32); // Syntax error |
| 67 | + } |
| 68 | + ``` |
| 69 | + |
| 70 | +4. Slightly more complicated syntax analysis for LL style parsers. The parser |
| 71 | + must guess if it currently parses a pattern or a type. |
| 72 | + |
| 73 | +5. Small complications for source code analyzers (e.g. [IntelliJ Rust]) and |
| 74 | + potential alternative implementations. |
| 75 | + |
| 76 | +6. Potential future parsing ambiguities with named and default parameters |
| 77 | + syntax. |
| 78 | + |
| 79 | + |
| 80 | +None of these issues is significant, but they exist. |
| 81 | + |
| 82 | +[historic accident]: https://github.com/rust-lang/rust/pull/29406#issuecomment-151859611 |
| 83 | +[IntelliJ Rust]: https://github.com/intellij-rust/intellij-rust/commit/1bb65c47341a04aecef5fa6817e8b2b56bfc9abb#diff-66f3ba596f0ecf74a2942b3223789ab5R41 |
| 84 | + |
| 85 | + |
| 86 | +# Detailed design |
| 87 | +[design]: #detailed-design |
| 88 | + |
| 89 | +Removing anonymous parameters from the language is formally a breaking change. |
| 90 | +The breakage can be trivially and automatically fixed by adding `_:` (suggested by @nagisa): |
| 91 | + |
| 92 | +```Rust |
| 93 | +trait T { |
| 94 | + fn foo(_: i32); |
| 95 | + |
| 96 | + fn bar_with_default_impl(_: String, _: String) { |
| 97 | + |
| 98 | + } |
| 99 | +} |
| 100 | +``` |
| 101 | + |
| 102 | +However this is also a major breaking change from the practical point of view. |
| 103 | +Parameter names are rarely omitted, but it happens. For example, |
| 104 | +`std::fmt::Display` is currently defined as follows: |
| 105 | + |
| 106 | +```Rust |
| 107 | +trait Display { |
| 108 | + fn fmt(&self, &mut Formatter) -> Result; |
| 109 | +} |
| 110 | +``` |
| 111 | + |
| 112 | +So the proposal is just to deprecate this syntax in the hope that the removal |
| 113 | +would become feasible and practical in the future. The hypothetical future may |
| 114 | +include: |
| 115 | + |
| 116 | +* Rust 2.0 release. |
| 117 | +* A tool to automatically fix deprecation warnings. |
| 118 | +* Storing crates on crates.io in "elaborated" syntax independent format. |
| 119 | + |
| 120 | +Enabling deprecation early makes potential future removal easier in practice. |
| 121 | + |
| 122 | + |
| 123 | +# Drawbacks |
| 124 | +[drawbacks]: #drawbacks |
| 125 | + |
| 126 | +* Deprecation will require code changes without bringing any immediate benefits. |
| 127 | + Until the deprecation is turned into a hard error the underlying issues will |
| 128 | + stay. |
| 129 | + |
| 130 | +* It is not clear if it will ever be possible to remove this syntax entirely. |
| 131 | + |
| 132 | + |
| 133 | +# Alternatives |
| 134 | +[alternatives]: #alternatives |
| 135 | + |
| 136 | +* Status quo. |
| 137 | + |
| 138 | +* Decide on the precise removal plan prior to deprecation. |
| 139 | + |
| 140 | +* Try to solve the underlying annoyances in some other way. For example, |
| 141 | + unbounded look ahead can be used in the parser to allow both anonymous |
| 142 | + parameters and the full pattern syntax. |
| 143 | + |
| 144 | + |
| 145 | +# Unresolved questions |
| 146 | +[unresolved]: #unresolved-questions |
| 147 | + |
| 148 | +* How often are anonymous parameters used in practice? There is a rough |
| 149 | + estimate: Servo and its dependencies omit parameter names 34 times. |
| 150 | + |
| 151 | +* Is there a consensus that anonymous parameters are not a useful language |
| 152 | + feature? |
0 commit comments